home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-12-31 | 110.9 KB | 3,126 lines | [TEXT/R*ch] |
- Received-Date: Mon, 8 Aug 1994 16:14:03 +0200
- From: pottier@clipper.ens.fr (Francois Pottier)
- Subject: csmp-digest-v3-049
- To: csmp-digest@ens.fr
- Date: Mon, 8 Aug 1994 16:13:56 +0200 (MET DST)
- X-Mailer: ELM [version 2.4 PL23]
- Mime-Version: 1.0
- Content-Type: text/plain; charset=ISO-8859-1
- Content-Transfer-Encoding: 8bit
- Errors-To: listman@ens.fr
- Reply-To: pottier@clipper.ens.fr
- X-Sequence: 54
-
- C.S.M.P. Digest Mon, 08 Aug 94 Volume 3 : Issue 49
-
- Today's Topics:
-
- CODE resources 101
- Can I do this with the Thread Manager?
- Dice Rolling - answers
- Easy file access functions [source]
- How to detect whether Debugger is installed?
- Q: Converting PB to FSSpec
- Q: Reentrancy and PowerMac Runtime Model
- Std filter proc trashes register D3!
- Which NIM for serial port info?
-
-
-
- The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
- (pottier@clipper.ens.fr).
-
- The digest is a collection of article threads from the internet newsgroup
- comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi-
- regularly and want an archive of the discussions. If you don't know what a
- newsgroup is, you probably don't have access to it. Ask your systems
- administrator(s) for details. If you don't have access to news, you may
- still be able to post messages to the group by using a mail server like
- anon.penet.fi (mail help@anon.penet.fi for more information).
-
- Each issue of the digest contains one or more sets of articles (called
- threads), with each set corresponding to a 'discussion' of a particular
- subject. The articles are not edited; all articles included in this digest
- are in their original posted form (as received by our news server at
- nef.ens.fr). Article threads are not added to the digest until the last
- article added to the thread is at least two weeks old (this is to ensure that
- the thread is dead before adding it to the digest). Article threads that
- consist of only one message are generally not included in the digest.
-
- The digest is officially distributed by two means, by email and ftp.
-
- If you want to receive the digest by mail, send email to listserv@ens.fr
- with no subject and one of the following commands as body:
- help Sends you a summary of commands
- subscribe csmp-digest Your Name Adds you to the mailing list
- signoff csmp-digest Removes you from the list
- Once you have subscribed, you will automatically receive each new
- issue as it is created.
-
- The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
- Questions related to the ftp site should be directed to
- scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
- digest are available there.
-
- Also, the digests are available to WAIS users. To search back issues
- with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
- http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
-
-
- -------------------------------------------------------
-
- >From ikb_macd@ECE.Concordia.CA (Keith MacDonald)
- Subject: CODE resources 101
- Date: Fri, 15 Jul 1994 05:30:50 GMT
- Organization: ECE - Concordia University
-
-
- I'd like to be able to distribute files (aka plug-ins) to add features
- to a program I'm working on. These files would (I assume) contain code
- resources. I've not been able to find any examples or clear description
- of what I need to do to achieve this. I'm using Pascal, but I imagine
- C works in a similar manner.
-
- Also related to code resources -
- would it be possible to have a C PPC native code resource used by
- a non-native (written in Think Pascal) application?
-
- Thanks,
- Keith
- ..............................................................................
- Keith MacDonald A bridge is not a high place
- ikb_macd@ece.concordia.ca The fifty-second floor
- Computer Engineering Icarus would know
- Concordia University A mountain isn't far to fall
- Montreal, QC, CANADA When you've fallen from the moon
- - Marillion
-
- +++++++++++++++++++++++++++
-
- >From mathews@ns9000.furman.edu (Owen Mathews)
- Date: 15 Jul 1994 17:03:44 GMT
- Organization: furman university computing center
-
- Keith MacDonald (ikb_macd@ECE.Concordia.CA) wrote:
-
- : I'd like to be able to distribute files (aka plug-ins) to add features
- : to a program I'm working on. These files would (I assume) contain code
- : resources. I've not been able to find any examples or clear description
- : of what I need to do to achieve this. I'm using Pascal, but I imagine
- : C works in a similar manner.
-
- : Also related to code resources -
- : would it be possible to have a C PPC native code resource used by
- : a non-native (written in Think Pascal) application?
-
- Using code resources to add functionality to an existing program doesn't
- require too much modification. You can "call" a code resource just like
- calling a function (see code example below). The main concept to under-
- stand is that code resources can be compiled from souce files just as
- an application can be. The compiler should let you do this when you are
- setting all of the options for compiling and linking (in SC++, the menu
- option is "Set Project Type"). When the resource is called, the entry
- point is simply the main procedure of the file.
-
- For more info, see IM.
-
- ********************this code example was taken from
- ********************Think Reference, copyright Symantec corp.
-
- // Calling a Code Resource
- // The following code illustrates how to call a
- // code resource. The code resource that we
- // are calling is given at the end
-
- // Assuming inclusion of <MacHeaders>
-
- typedef void (*MyProcPtr) (int); // Define a procedure pointer
- // for the code resource
- void DoError (OSErr err);
- main ()
- {
- Handle myCRHandle;
- ProcPtr myCRPtr;
- int integerParam;
-
- myCRHandle = GetNamedResource ('ALCT', "\pmyBeep");
- if (myCRHandle == nil)
- DoError (ResError());
- else
- {
- HLock (myCRHandle);
- (* (MyProcPtr) (*myCRHandle)) (integerParam);
- HUnlock (myCRHandle);
- }
- }
-
- /*********************************************
- Here is the code resource that we're calling
-
- void main (int i)
- {
- int j;
-
- for (j = 0; j < i; j++)
- SysBeep (5);
- }
- **********************************************/
-
-
- : Also related to code resources -
- : would it be possible to have a C PPC native code resource used by
- : a non-native (written in Think Pascal) application?
-
- PPC macs do not use the same kind of CODE resources that 68k macs do.
- Instead of keeping their program code in the resource fork, divided into
- 32K segments, PowerMacs keep code in the *data* fork of a file. It may
- be possible to call a PPC code chunk from a Pascal application (using the
- mixed-mode manager), but it will be a little different than calling a
- 68k code resource.
-
- --
- Owen Mathews mathews@furman.edu
- <><><><><><><><><><><><><><><><><><><><>
- Furman University, Computer Science Dept
-
-
- +++++++++++++++++++++++++++
-
- >From tyen@netcom.com (Anthony Yen)
- Date: Sat, 16 Jul 1994 09:13:13 GMT
- Organization: NETCOM On-line Communication Services (408 261-4700 guest)
-
- In article <306fhg$fl8@ns9000.furman.edu>,
- Owen Mathews <mathews@ns9000.furman.edu> wrote:
- >PPC macs do not use the same kind of CODE resources that 68k macs do.
- >Instead of keeping their program code in the resource fork, divided into
- >32K segments, PowerMacs keep code in the *data* fork of a file. It may
- >be possible to call a PPC code chunk from a Pascal application (using the
- >mixed-mode manager), but it will be a little different than calling a
- >68k code resource.
-
- Hmm...several questions come to mind as I read this:
-
- Has anyone seen how to support calling PPC-native code from within a
- PPC-native app? And from within a fat-app?
-
- If I append some application-specific data to the data fork of a
- fat-app, it won't confuse the loader or whatever else Apple might have
- in store for the data fork in the future, right? <hope, hope, cross
- fingers>
-
- Is there a convention for writing fat-code? That is, can I just build
- a CODE resource for 68K, then do what I normally do to build a fat-app
- but wave the magic wand over the CODE resource instead, and append the
- PPC code onto that resource file and wind up with a fat-loadable code
- module? If I can, is there a single calling convention for both
- loadable code modules (this refers back to my first question)?
-
- Finally, the THINK Reference code sample appears to add two
- dereferences over the standard function call overhead when calling a
- code resource. Is this correct? If it is correct, in the grand
- scheme of things this would not matter, but I may get down to shaving
- cycles in the future and if so I may need to have all code resources
- locked down in memory and as fully dereferenced as possible. Offhand,
- I see only one dereference I could avoid, by making sure the code
- resource is marked locked and getting a pointer out of the handle.
- But I'm getting a nagging feeling I'm missing something here...
- --
-
- Anthony Yen <tyen@netcom.com> Austin, Texas, USA
-
- +++++++++++++++++++++++++++
-
- >From jwbaxter@olympus.net (John W. Baxter)
- Date: Sat, 16 Jul 1994 10:03:43 -0700
- Organization: Internet for the Olympic Peninsula
-
- In article <tyenCt10A2.CsB@netcom.com>, tyen@netcom.com (Anthony Yen) wrote:
-
- > In article <306fhg$fl8@ns9000.furman.edu>,
- > Owen Mathews <mathews@ns9000.furman.edu> wrote:
- > >PPC macs do not use the same kind of CODE resources that 68k macs do.
- > >Instead of keeping their program code in the resource fork, divided into
- > >32K segments, PowerMacs keep code in the *data* fork of a file. It may
- > >be possible to call a PPC code chunk from a Pascal application (using the
- > >mixed-mode manager), but it will be a little different than calling a
- > >68k code resource.
- >
- > Hmm...several questions come to mind as I read this:
- >
- > Has anyone seen how to support calling PPC-native code from within a
- > PPC-native app? And from within a fat-app?
-
- Widely available for some time now.
- Inside Mac: PowerPC System Software
- various "develop" articles
- various "MacTech" articles
-
- > If I append some application-specific data to the data fork of a
- > fat-app, it won't confuse the loader or whatever else Apple might have
- > in store for the data fork in the future, right? <hope, hope, cross
- > fingers>
-
- The resource which tells the system where to look for the code fragment(s)
- provides for this. But it's probably cleaner not to put variable-length
- data in there, or even mutable but fixed length data.
-
- > Is there a convention for writing fat-code? That is, can I just build
- > a CODE resource for 68K, then do what I normally do to build a fat-app
- > but wave the magic wand over the CODE resource instead, and append the
- > PPC code onto that resource file and wind up with a fat-loadable code
- > module? If I can, is there a single calling convention for both
- > loadable code modules (this refers back to my first question)?
-
- Above references.
-
- --
- John Baxter Port Ludlow, WA, USA [West shore, Puget Sound]
- No hablo Intel.
- jwbaxter@pt.olympus.net
-
- +++++++++++++++++++++++++++
-
- >From winter@ai.rl.af.mil (Jim Wintermyre)
- Date: Tue, 19 Jul 1994 19:23:13 GMT
- Organization: Rome Laboratory
-
- In article <CsyvBJ.Ku3@newsflash.concordia.ca>
- ikb_macd@ECE.Concordia.CA (Keith MacDonald) writes:
-
- > to a program I'm working on. These files would (I assume) contain code
- > resources. I've not been able to find any examples or clear description
- > of what I need to do to achieve this. I'm using Pascal, but I imagine
-
- Check out MacTech vol. 9 no. 9 (Sept 93), "External Code Modules in
- Pascal." Also check out the tech note "Stand-Alone Code ad nauseum."
-
- > Also related to code resources -
- > would it be possible to have a C PPC native code resource used by
- > a non-native (written in Think Pascal) application?
-
- I believe so, but I'm not sure of the details. Check out the Mixed
- Mode and Code Fragment Manager chapters in New Inside Mac: Power PC
- System Software.
-
- Jim Wintermyre (Opinions expressed are my own, of course)
-
- winter@ai.rl.af.mil
- wintermyrej@lonex.rl.af.mil
-
- ---------------------------
-
- >From amundson@phenom.physics.wisc.edu (James F. Amundson)
- Subject: Can I do this with the Thread Manager?
- Date: Sat, 16 Jul 1994 21:05:16 -0600
- Organization: Division of Information Technology
-
- Can someone tell me if what I have in mind is possible? I want to use the
- Thread Manager to give me basic preemptive multitasking without much
- thought.
-
- My situation is this: I'm not writing a Mac application. I'm using Think C
- 7.0 to run scientific calculations. My programs are entirely ANSI C with
- no toolbox calls other than those from the Think C ANSI libraries. I'd
- like to be able to run the programs I write without taking over my mac
- while they run. In the past, I've hacked them to call WaitNextEvent
- occasionally. The problem is that it takes a fair amount of effort on my
- part to decide where and how often I need to call WNE. Since the nature of
- my work involves constantly changing the programs I'm writing, adjusting
- my calls to WNE every time is impractical.
-
- Can I use the Thread Manager without much effort? Are there any examples
- of this sort of thing?
-
- Any advice will be appreciated.
-
- Thanks,
-
- Jim Amundson
-
- +++++++++++++++++++++++++++
-
- >From first.ascent@mindlink.bc.ca (Alex Curylo)
- Date: 17 Jul 1994 03:17:02 GMT
- Organization: MIND LINK! Communications Corp.
-
- In article <amundson-1607942105160001@f180-186.net.wisc.edu>
- amundson@phenom.physics.wisc.edu (James F. Amundson) writes:
-
- > Can I use the Thread Manager without much effort? Are there any examples
- > of this sort of thing?
-
- Grab develop 17, and a copy of CodeWarrior 3.5. The latest iteration of
- PowerPlant includes a nice selection of thread classes. They're being
- used in a project I'm working on right now, and the fellow using them
- seems to have fairly positive regard for them. And for the rest of
- PowerPlant, as soon as they finish it ;)
-
- +++++++++++++++++++++++++++
-
- >From rmah@panix.com (Robert Mah)
- Date: Sun, 17 Jul 1994 00:53:05 -0500
- Organization: One Step Beyond
-
- amundson@phenom.physics.wisc.edu (James F. Amundson) wrote:
-
- ) I'm using Think C 7.0 to run scientific calculations. My programs are
- ) entirely ANSI C with no toolbox calls other than those from the Think
- ) C ANSI libraries. I'd like to be able to run the programs I write
- ) without taking over my mac while they run. In the past, I've hacked
- ) them to call WaitNextEvent occasionally. The problem is that it takes
- ) ...
- ) Can I use the Thread Manager without much effort? Are there any examples
- ) of this sort of thing?
-
- Thread Manager can do pre-emptive threads, _but_ only on 68K Macs. In
- addition, pre-emptive threads must obey the same rules as interupt level
- code. I.e. no drawing, no moving memory, etc.
-
- There's examples in Develop 17 that goes over using the Thread Mgr, but
- since using co-operative threads won't gain you much (you'll still have
- to call Yield() occaisionally) you should look at your code and see if
- you can use pre-emptive threads.
-
- Cheers,
- Rob
- _____________________________________________________________________
- Robert S. Mah : Macintosh software development : 212.947.6507
- One Step Beyond : and network consulting : rmah@panix.com
-
- +++++++++++++++++++++++++++
-
- >From gwatts@fnal.fnal.gov (Gordon Watts)
- Date: Mon, 18 Jul 1994 00:09:54 -0600
- Organization: Fermi Lab
-
- In article <rmah-1707940053050001@rmah.dialup.access.net>, rmah@panix.com
- (Robert Mah) wrote:
-
- > amundson@phenom.physics.wisc.edu (James F. Amundson) wrote:
- >
- > ) I'm using Think C 7.0 to run scientific calculations. My programs are
- > ) entirely ANSI C with no toolbox calls other than those from the Think
- > ) C ANSI libraries. I'd like to be able to run the programs I write
- > ) without taking over my mac while they run. In the past, I've hacked
- > ) them to call WaitNextEvent occasionally. The problem is that it takes
- > ) ...
- > ) Can I use the Thread Manager without much effort? Are there any examples
- > ) of this sort of thing?
- >
- > Thread Manager can do pre-emptive threads, _but_ only on 68K Macs. In
- > addition, pre-emptive threads must obey the same rules as interupt level
- > code. I.e. no drawing, no moving memory, etc.
- >
- > There's examples in Develop 17 that goes over using the Thread Mgr, but
- > since using co-operative threads won't gain you much (you'll still have
- > to call Yield() occaisionally) you should look at your code and see if
- > you can use pre-emptive threads.
- >
- > Cheers,
- > Rob
-
- It depends upon what ANSI C library calls you make. If you make calls to
- printf, etc. then the short answer is ... well, no. Calls to things like
- sqrt, etc. are ok. Basically, any call that will cause the screen to be
- drawn to or memory to be moved (malloc, etc.) will break with the
- pre-emptive threads.
-
- There are two things you can do, if you still want to use the threads.
- First, you can isolate your calls to printf and the like so they are never
- called in a preemptive thread (a thread is preemptive or cooperative when
- it is created, and cannot change during its lifetime).
-
- Second, and perhaps simpler, is you can implement your calculation as a
- cooperative thread. Sprinkle calls to "Yield()" all over the place, but
- don't worry too much about the placement. Just make sure there are enough
- of them. Now, in your main event loop you can put something like the
- following (this code has not been compiled/debugged!):
-
- while (!gDone) { // gDone will be set by your calc when it is finished...
-
- current_time = TickCount () + 30; // Current time plus 1/2 a second
-
- while (current_time > TickCount ())
- Yield (); // Go off and do some real calculations for a 1/2 second
-
- WaitNextEvent (...);
- }
-
- Excuse the formatting... You will incure dead time in the Yield call, I'm
- not sure how much speed you are trying to get out. The fact that you are
- calling WaitNextEvent means that you are willing to give up some time...
- This will require little modification to your current application, I
- suspect.
-
- One bad thing about using threads if you have to figure out what your
- stack usage is before you run your calculation -- threads don't have a
- stack that grows as need be. This might be bad if you are doing lattice
- calculations and allocate large arrays on the stack (do it globally at
- compile time or by malloc while running).
-
- You can use all calls in cooperative threads, printf, malloc, etc. etc.
- and they will work on the powerpc.
-
- Cheers,
- Gordon (high energy physics).
-
- --
- Gordon Watts -- gwatts@fnal.fnal.gov
-
- +++++++++++++++++++++++++++
-
- >From Dave Falkenburg <falken@apple.com>
- Date: Wed, 20 Jul 1994 16:43:41 GMT
- Organization: Apple Computer, Inc.
-
- In article <gwatts-1807940009540001@slip113.fnal.gov> Gordon Watts,
- gwatts@fnal.fnal.gov writes:
- >while (!gDone) { // gDone will be set by your calc when it is
- finished...
- >
- > current_time = TickCount () + 30; // Current time plus 1/2 a second
- >
- > while (current_time > TickCount ())
- > Yield (); // Go off and do some real calculations for a 1/2 second
- >
- > WaitNextEvent (...);
- >}
-
-
- GACK!
-
- Please use a dynamic value for adjusting sleep timings like this: i.e.
- replace the "+30" with "+gRunQuantum", a value that is computed
- dynamically based on the compute power of the CPU. The code above means
- that even if we make the MacOS 100x faster, you might limit the ability
- for the user to switch applications down to once every two seconds.
-
- HALF A SECOND IS ALOT OF CPU TIME TO BE EATING without yielding control
- to other applications.
-
- -Dave Falkenburg
- -Apple Computer, Inc.
-
- ---------------------------
-
- >From cconstan@epdiv1.env.gov.bc.ca (Carl B. Constantine)
- Subject: Dice Rolling - answers
- Date: Thu, 21 Jul 1994 08:12:12 -0700
- Organization: Ministry of Environment, Lands & Parks
-
- Finally, after much fiddling and examining of code, I finally got my dice
- animation working in my game. There is a trick to it.
-
- Because many people helped me, I thought I would post what I found so that
- others can be helped too.
-
- First, a little background. I use 3 global GWorlds to hold (a) all six
- dice from a PICT resource, (b) the mask and (c) a working area. This set
- up is similar to how john calhoun did his games like Glypa II. As
- mentioned above, these are all global, so I can access them from
- anywhere. I also use a custom window record structure that includes a
- GWorld which has the contents of the window in it. This is used for
- really fast updates (See Mac Prog. Secrets, ch 6 for more details)
-
- Now that all the GWorlds are set up and the items are in them, I use
- CopyMask (speed is not important in this game) to copy the dice from the
- diceWorld and the mask from the maskWorld to the workWorld. (with me so
- far?) This is a simple call. I use it twice as I have 2 dice I want to
- display and "roll". I can then use CopyBits to copy the workWorld to my
- window's offscreen GWorld for updating purposes. No problems here.
-
- The trick comes when you want to copy the dice from the GWorld to the
- window. When you use GWorlds, you always use GetGWorld and SetGWorld when
- copying from 1 GWorld to another. However, if you use this when you want
- to copy to the window, CopyBits makes your Mac CRASH big time!! (I ran
- this in the debugger in THINK C 7.0.3 and I still couldn't get out.
- cmd-opt-esc didn't do much, I had to restart. I have an LCIII with 12MB
- RAM). So what you have to do is use GetPort and SetPort when copying to
- the window. This works without a hitch.
-
- I then use CopyMask as I did before to copy the dice to the workWorld and
- CopyBits to copy from the workWorld to the window. This is still pretty
- fast despite the intermediate steps. I've seen some code by Tony Myles
- that I got off of ftp.apple.com called CopyBits vs. CopyMask. He uses
- CopyBits with a maskRgn to copy to the window. This is much faster. But
- like I said, I don't need speed. Also, you can just plain elimate the
- intermate step and CopyMask directly to the window instead of the
- workWorld and then the window.
-
- Thanks to many people on the Net for donating code (Ken Long) and help
- (Aaron Giles, Ingemar R., et al.) so that I can actually get this to work.
-
- --
- ========================================================================
- Carl B. Constantine B.C. Environment, Lands & Parks
- End-User Support Analyst CCONSTAN@epdiv1.env.gov.bc.ca
- PGP Key available if you finger: CCONSTAN@EUSACBC.env.gov.bc.ca
-
- +++++++++++++++++++++++++++
-
- >From s828963@kub.nl (Peter Berck)
- Date: 22 Jul 1994 12:21:53 GMT
- Organization: KUB, The Netherlands
-
- In article <cconstan-2107940812120001@eusacbc.env.gov.bc.ca>, cconstan@epdiv1.env.gov.bc.ca (Carl B. Constantine) writes:
- |> Finally, after much fiddling and examining of code, I finally got my dice
- |> animation working in my game. There is a trick to it.
- |>
- |> Because many people helped me, I thought I would post what I found so that
- |> others can be helped too.
- |>
- [snip]
- |>
- |> The trick comes when you want to copy the dice from the GWorld to the
- |> window. When you use GWorlds, you always use GetGWorld and SetGWorld when
- |> copying from 1 GWorld to another. However, if you use this when you want
- |> to copy to the window, CopyBits makes your Mac CRASH big time!! (I ran
- |> this in the debugger in THINK C 7.0.3 and I still couldn't get out.
- |> cmd-opt-esc didn't do much, I had to restart. I have an LCIII with 12MB
- |> RAM). So what you have to do is use GetPort and SetPort when copying to
- |> the window. This works without a hitch.
-
- Uhm? Are you sure? I am writing a program which also has an offscreen
- GWorld which is copied to the screen (using CopyBits) when necessary.
- I use SetGWorld and GetGWorld all the time. In fact, NIM:Imaging with
- QuickDraw mentions somewhere (don't have it on me, so I can't give you
- the page number) that you should use SetGWorld/GetGWorld instead of
- GetPort and SetPort.
-
- Now I'm slightly confused. I have just started to use GWorld stuff,
- and I was pretty sure that Get/SetGWorld was all I needed, so if any
- macguru can enlighten me I'd be very grateful...
-
- -Peter
-
- - ----------------------------------------------------------------
- P.J.Berck@kub.nl pgp-pubkey on request
- (format t "~&~{~<~%~1:;~a~>~^,~}.~%"
- '(DoD#-337 The-Ex Sonic-Youth NIN Dante-Alighieri Guinness))
-
- +++++++++++++++++++++++++++
-
- >From cconstan@epdiv1.env.gov.bc.ca (Carl B. Constantine)
- Date: Fri, 22 Jul 1994 11:30:50 -0700
- Organization: Ministry of Environment, Lands & Parks
-
- In article <30odl1$7ro@kubds1.kub.nl>, P.J.Berck@kub.nl wrote:
-
- > In article <cconstan-2107940812120001@eusacbc.env.gov.bc.ca>,
- cconstan@epdiv1.env.gov.bc.ca (Carl B. Constantine) writes:
- > |> Finally, after much fiddling and examining of code, I finally got my dice
- > |> animation working in my game. There is a trick to it.
- > |>
- > |> Because many people helped me, I thought I would post what I found so that
- > |> others can be helped too.
- > |>
- > [snip]
- > |>
- > |> The trick comes when you want to copy the dice from the GWorld to the
- > |> window. When you use GWorlds, you always use GetGWorld and SetGWorld when
- > |> copying from 1 GWorld to another. However, if you use this when you want
- > |> to copy to the window, CopyBits makes your Mac CRASH big time!! (I ran
- > |> this in the debugger in THINK C 7.0.3 and I still couldn't get out.
- > |> cmd-opt-esc didn't do much, I had to restart. I have an LCIII with 12MB
- > |> RAM). So what you have to do is use GetPort and SetPort when copying to
- > |> the window. This works without a hitch.
- >
- > Uhm? Are you sure? I am writing a program which also has an offscreen
- > GWorld which is copied to the screen (using CopyBits) when necessary.
- > I use SetGWorld and GetGWorld all the time. In fact, NIM:Imaging with
- > QuickDraw mentions somewhere (don't have it on me, so I can't give you
- > the page number) that you should use SetGWorld/GetGWorld instead of
- > GetPort and SetPort.
- >
- > Now I'm slightly confused. I have just started to use GWorld stuff,
- > and I was pretty sure that Get/SetGWorld was all I needed, so if any
- > macguru can enlighten me I'd be very grateful...
- >
-
- It crashed my mac considerably. However, I'm piggybacking a GWorldPtr
- onto a custom windowRecord structure. this may be why it's crashing. I'm
- not sure, I haven't tested it otherwise (I don't have NIM: Imaging). I'd
- have to test.
-
- I have it off hand from a good source (Aaron Giles, writer of JPEGView)
- that you SHOULD always used GetGWorld & SetGWorld. I'm not sure why it
- was crashing in my system, but it was so I left it with GetPort & SetPort.
-
- Hope this helps.
-
- --
- ========================================================================
- Carl B. Constantine B.C. Environment, Lands & Parks
- End-User Support Analyst CCONSTAN@epdiv1.env.gov.bc.ca
- PGP Key available if you finger: CCONSTAN@EUSACBC.env.gov.bc.ca
-
- +++++++++++++++++++++++++++
-
- >From kenlong@netcom.com (Ken Long)
- Date: Sat, 23 Jul 1994 14:24:16 GMT
- Organization: NETCOM On-line Communication Services (408 261-4700 guest)
-
- Here are some fragments/snippets from Mark Hanrek, on the subjuct, ala
- NuCube (some names changed for another program):
-
- - -----------
- WindowPtr starsWindow; // Windows and GWorlds are the same thing, so
- GWorldPtr gOffscreenGWorld; // use only Get/SetGWorld calls in
- // this app.screen" area in the window
- Rect gOffscreenRect; // The offscreen rect's upper-left is 0,0
- Rect gProjectionRect; // The projection Rect
-
- //*******************************************************************//
- // Create window, offscreen GWorld, and one control for starters //
- //*******************************************************************//
-
- void SetupWindow (void)
- {
- Rect tempRect;
-
- //------ Set up our main window, man
-
- starsWindow = GetNewWindow (rWIND, nil, (WindowPtr) -1L);
-
- SetPort (starsWindow);
- ShowWindow (starsWindow);
-
- SetRect (&gProjectionRect, kHorizOffset, kVertOffset,
- kHorizOffset+kCubeSide, kVertOffset+kCubeSide);
-
- //% Set up an offscreen GWorld for preparing the next cube's image.
- SetRect (&gOffscreenRect, 0, 0, kCubeSide, kCubeSide);
-
- gOffscreenGWorld = CreateOffscreenGWorld (&gOffscreenRect);
-
- }
-
- void RotateCubeOnce (void)
- {
- long ticksNow;
- GWorldPtr windowGW;
- GDHandle windowGD;
- PixMapHandle thePixMap;
-
- GetGWorld (&windowGW, &windowGD); // Save whatever we had before
-
- SetGWorld (gOffscreenGWorld, nil);
-
- if (LockPixels (thePixMap = GetGWorldPixMap (gOffscreenGWorld)))
- {
- EraseRect (&gOffscreenGWorld->portRect);
-
- //======================================================
- (action)
- //======================================================
- //
- // Always set the current port to a window's port before
- // drawing from
- // a GWorld, so that the Window Manager can "clip" the
- // image properly
- // should there be other windows in front. Comment out
- // the next statement
- // and notice what happens when you drag another window in front of
- // the NuCube window. :)
- //
-
- SetGWorld (windowGW, windowGD); // Focus on a real window
-
- CopyBits ((BitMapPtr)*thePixMap,
- (BitMapPtr)&starsWindow->portBits,
- &gOffscreenRect,
- &gProjectionRect, srcCopy, nil);
-
- UnlockPixels (thePixMap);
- }
- SetGWorld (windowGW, windowGD); // Okay if this is redundant
- }
-
- //*******************************************************************//
- // Use the following function for the rest of your programming
- // days.
- // Do not alter it in any way. It is a complete functional unit
- // doing all REQUIRED things.
- //*******************************************************************//
-
- GWorldPtr CreateOffscreenGWorld (Rect *theRect)
- {
- CGrafPtr currentPort;
- GDHandle currentGDevice;
- GWorldPtr offScreen;
- QDErr result;
-
- GetGWorld (¤tPort, ¤tGDevice);
-
- //-- If there is not enough application memory, try MultiFinder
- //-- temporary memory.
-
- if ((result = NewGWorld (&offScreen, 0, theRect, nil, nil, 0L))
- != noErr)
- if ((result = NewGWorld (&offScreen, 0, theRect, nil,
- nil, useTempMem)) != noErr)
- return (nil);
-
- SetGWorld (offScreen, nil);
-
- //-- Initialize the clipping "hole" to be the same as the
- //-- drawing area.
-
- ClipRect (&offScreen->portRect);
-
- //-- The GWorld has random stuff in it, so we'll erase it to
- //-- white.
-
- if (LockPixels (GetGWorldPixMap (offScreen)))
- {
- ForeColor (blackColor);
- BackColor (whiteColor);
- EraseRect (&offScreen->portRect);
- UnlockPixels (GetGWorldPixMap (offScreen));
- }
-
- SetGWorld (currentPort, currentGDevice);
- return offScreen;
- }
-
- //*******************************************************************//
- // Shut down with charm, grace and decorum.
- //*******************************************************************//
-
- void MoveAlongHome (void)
- {
- DisposeWindow (starsWindow); // Not "CloseWindow"
- DisposeGWorld (gOffscreenGWorld);
- }
-
- - --------------
- That's all, folks.
-
- -Ken-
-
- ---------------------------
-
- >From rkwee@ee.pdx.edu (Roland Kwee)
- Subject: Easy file access functions [source]
- Date: 18 Jul 1994 20:35:28 -0700
- Organization: (none)
-
- Some days ago I promised to upload some source code that makes handling
- Mac file functions as easy as the standard ANSI C library functions.
- Hopefully I didn't leave out code that is essential to understand and
- use my little system.
-
- Here is my Macintosh ThinkC source code for accessing files pretty much like
- with the ANSI C library functions. Hopefully the code is sufficiently
- commented to be understandible. Note that there is a test function that
- demonstrates how to use the other functions.
-
- Please let me know if this is useful, understandable, and if you see
- problems or improvements.
-
- --Roland Kwee email: RolandKwee@ACM.org
-
- /*----------------------------------------------------------------------------------
- * globals.h Roland Kwee May 25, 1994
- * This file contains the declarations for the application-specific global data.
- *
- * A good strategy may be to declare a number of global variables in a single
- * structure. With the menu options, the user can change one or more of these
- * global settings. These settings are global to allow easy access by the
- * functions that actually perform tasks. By keeping them in a single
- * structure, they are easy to keep track of.
- *----------------------------------------------------------------------------------
- */
-
- #ifndef __GLOBALS_H__
- #define __GLOBALS_H__
-
- enum Creators{CREATOR='TrRK'};
-
- enum FileTypes{UNKNOWN, PostScript, Binary,
- TextDos, TextUnix, TextMac,
- Hathaway, Rochester, RochesterHeader, BEN5000,
- PPSM, Support, Spreadsheet};
-
- /* This structure communicates user input to the process. */
- struct Option_s{
- int Quit;
- int SeparateDigCh, OutputType, LPFcorrection, DiagnosticWindow, ProgressDialog, Fast;
- int debug, test_partly; /* default: 0 (no debug output). */
- void *OpenFileList, *PrintFileList;
- float TimeZoneHourOffset;
- char DefaultLocation[5];
- };
-
- extern struct Option_s Option;
-
- #endif /* __GLOBALS_H__ */
-
-
-
-
- /* MacFile.h Roland Kwee June 1, 1994
- * Functions to make handling files on the Mac almost as easy as in Unix.
- * This will make it possible to port programs between Unix and the Mac.
- */
-
-
- #ifndef _MACUTIL_H__
- #define _MACUTIL_H__
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
-
- //==============
- // Project Info:
- //==============
- // compiler: Symantec C++ for Macintosh, 1994, ThinkC (version 7 ?)
- // libraries: MacTraps, SANE, ANSI
-
- // Executable:
- // file name: Translate
- // File Type: APPL, Creator: TrRK
-
- // Compiler settings:
- // int: 2 bytes
- // float: 4 bytes
- // double: 8 bytes
- // don't use the "native" floating point format
- #if __option(native_fp)
- #error Don't use the "native" floating point format (Edit/Options/Compiler settings).
- #endif
- // printf can only handle float and doubles if double is not set to 8 bytes:
- #if __option(double_8)
- #error Don't set doubles to 8 bytes (Edit/Options/Compiler settings).
- #endif
- // REASONS FOR FLOATING POINT SETTINGS:
- // The input file has IEEE double numbers, but the input routine is able to convert these
- // to Mac format using the Mac type `short double' which is equal to IEEE double.
- // The library function printf is compiled with the standard settings, so the formats for
- // floating point will work incorrectly if the program is compiled with the `8-byte doubles' option.
- // Better not to recompile the library, so set all floating point options to Mac standard.
-
-
-
- /* ===============definitions for byte order ===================== */
- enum {BigEndian /* Motorola, VAX */, LittleEndian /* Intel */};
-
- //extern int computerbyteorder;
- #define computerbyteorder BigEndian
-
- /*=========================== TIME ZONE ============================*/
- /* This should be a menu option. For now it is constant.
- * Valid values are -12.0 .. 12.0. Positive is East of Greenwich.
- * Simple fractions like 9.5 (Adelaide, Australia) should work.
- */
- #define TZ -7
-
- /* This global can be used with sprintf to prepare a string to pass to Log(). */
- extern char buf[1000];
-
- void Log(char *msg);
- void SystemError(char *msg, char *source, int code);
- void Warn(char *msg);
- char *PtoCstrPtr(void *Pstring);
- void LtoCstr(OSType l, char *s);
- char *FSStoCstrPtr(FSSpec *file);
- char *GetBaseName(FSSpec *file);
- char *GetFullPathName(FSSpec *file);
- void GetFullPath(int VolumeSpec, long ParentDirID, char *fullPath);
- int FSSpecRoutinesAvail(void);
- FSSpec *select_input_file(const int numTypes, SFTypeList myTypes);
- FSSpec *select_output_file(const char *prompt, const char *defname);
- void FinderInfo(FSSpec *fs);
- void PathInfo(FSSpec *fs);
- char *GetVolumeName(FSSpec *fs);
- void VolumeInfo(FSSpec *fs);
- void TestPathUtils(void);
-
- #if 0 /* See Mac include file <files.h> */
- struct FSSpec {
- short vRefNum;
- long parID;
- Str63 name;
- };
- typedef struct FSSpec FSSpec;
- typedef FSSpec *FSSpecPtr, **FSSpecHandle;
- typedef FSSpecPtr FSSpecArrayPtr; /* pointer to array of FSSpecs */
- #endif
-
- typedef struct{
- int in_use; /* To maintain the file table. */
- FSSpec fss; /* Specification of the (closed) file selected with a dialog. */
- short refnum; /* Reference number, or access path of the open file. */
- int byteorder;
- }MacFILE;
-
- /* This structure is currently only used to hold the year of a file.
- * It doesn't really matter whether last access or last modify.
- */
- struct MacStat{
- long st_size; /* total size of file, in bytes */
- int year;
- #if 0
- time_t st_atime; /* file last access time */
- time_t st_mtime; /* file last modify time */
- time_t st_ctime; /* file last status change time */
- #endif
- };
-
- #define File MacFILE
- #define FileRead macfread
- #define FWRITE macfwrite
- #define FSEEK macfseek
- #define FSTAT macfstat
- #define STAT_T struct MacStat
-
- MacFILE *macftype(FSSpec *selection, long creator, long type);
- MacFILE *macfopen(FSSpec *selection, char *mode);
- int macfclose(MacFILE *fp);
- int macfread(void *buf, size_t recsize, size_t recnum, MacFILE *fp);
- int macfwrite(void *buf, size_t recsize, size_t recnum, MacFILE *fp);
- int macfseek(MacFILE *fp, long offset, int whence);
- long macftell(MacFILE *fp);
- int macfstat(MacFILE *fp, struct MacStat *buf);
- void copy_file(MacFILE *fp_in, MacFILE *fp_out);
- int TestFileType(MacFILE *fp);
- void TestFileUtils(void);
- void BetterMoveWindow(WindowPtr wp, float right, float down);
-
- void SwapN(void *buf, int n);
- int NeedSwap(MacFILE *fp, void *buf, int n);
-
- char GetInputByte(File *fp); // Reads and returns one byte.
- int GetInputInt(File *fp); // Reads, converts and returns one integer.
- long GetInputLong(File *fp);
- unsigned long GetInputULong(File *fp);
- float GetInputFloat(File *fp);
- double GetInputDouble(File *fp); /* reads IEEE 8-byte double, returns Mac double. */
-
- /* GetInputString - Reads a string and returns a null-terminated C-string.
- Reading stops when a '\0' char, or `size' characters have
- been read. A '\0' is added.
- If you are certain that the string to read is terminated with a '\0',
- then `size' can be the size of the buffer. Otherwise, the buffer needs to be
- one character bigger, to hold the added '\0'.
- */
- char *GetInputString(char *buf, int size, File *fp);
-
- /* GetInputNString - Reads n characters and returns a string in str.
- str needs to have room for an additional '\0'. */
- char *GetInputNString(char *str, int n, File *fp);
-
- /* SwapN - swaps n bytes of buf in place */
- void SwapN(void *buf, int n);
-
-
- // Writes a C string to the output file.
- int WriteTxt(File *fp, char *str);
-
- // Writes bytes to a binary output file.
- int WriteBin(File *fp, void *buf, int size);
-
- // Specialized functions to write data, argument may be a constant
- void WriteULong(File *fp, unsigned long x);
- void WriteLong(File *fp, long x);
- void WriteShort(File *fp, signed short x);
-
- #endif /* _MACUTIL_H__ */
-
-
- /* MacFile.c Roland Kwee June 1, 1994
- * Functions to make handling files on the Mac almost as easy as in Unix.
- * This will make it possible to port programs between Unix and the Mac.
- */
-
- #include "MacFile.h"
- #include "globals.h"
- #include <GestaltEqu.h>
- #include <console.h> /* cshow() */
-
- /* This global can be used with sprintf to prepare a string to pass to Log(). */
- char buf[1000];
-
- /*----------------------------------------------------------------------------------
- * Log() - Diagnostic output. Adds a newline at the end.
- *----------------------------------------------------------------------------------*/
- void Log(char *msg){
- if(Option.debug)
- puts(msg);
- return;
- }
-
- /*----------------------------------------------------------------------------------
- * SystemError() - Error output. Should be a alert box.
- *----------------------------------------------------------------------------------*/
- void SystemError(char *msg, char *source, int code){
-
- /* Force visible output. */
- if(!Option.debug){
- Option.debug=1;
- cshow(stdout);
- }
-
- sprintf(buf, "Error: %s%s%s code: %d", msg, source?" in function: ":"",
- source?source:"", code);
- Log(buf);
-
- return;
- }
-
- /*----------------------------------------------------------------------------------
- * Warn() - Warning output.
- *
- * Should be a modal dialog box IF the diagnostic window is closed.
- * Or, there should be an option to suppress the modal dialog box to
- * allow unattended transfer of large batches of files.
- *
- *----------------------------------------------------------------------------------*/
- void Warn(char *msg){
- Log(msg);
- return;
- }
-
- /*----------------------------------------------------------------------------------
- * PtoCstrPtr() - Converts a Pascal string to a pointer to a C String.
- * The string the pointer points to is reused for each new call.
- *----------------------------------------------------------------------------------*/
- char *PtoCstrPtr(void *Pstring){
- static char Cstring[257];
- char *str;
- int i, max;
-
- str=Pstring;
- max=str[0];
- memcpy(Cstring, str+1, max);
- Cstring[max]='\0';
- return Cstring;
- }
-
- /*----------------------------------------------------------------------------------
- * LtoCstr() - Converts an OSType (long) to a C-string (char[5]).
- *----------------------------------------------------------------------------------*/
- void LtoCstr(OSType l, char *s){
- //sprintf(buf, "LtoCstr: 0x%08X", l); Log(buf);
- memcpy(s, (char*)&l, 4);
- s[4]='\0';
- return;
- }
-
- /*----------------------------------------------------------------------------------
- * FSStoCstrPtr() - Converts a FSS file specification to a C string.
- * The string the pointer points to is reused for each new call.
- * See: New Inside Mac, "Files", p. 2-45: Constructing Full Pathnames, Listing 2-5.
- *----------------------------------------------------------------------------------*/
- char *FSStoCstrPtr(FSSpec *file){
- static char fullPath[300];
- CInfoPBRec myPB;
- Str255 dirName;
- OSErr myErr;
-
- strcpy(fullPath, PtoCstrPtr(file->name));/* Start with base file name. */
- myPB.dirInfo.ioNamePtr=dirName; /* Output buffer for PBGetCatInfo(). */
- myPB.dirInfo.ioVRefNum=file->vRefNum; /* Volume ID */
- myPB.dirInfo.ioDrParID=file->parID; /* Initialize parent dir. */
- myPB.dirInfo.ioFDirIndex= -1; /* <0: Use ioDrDirID as input. */
- myPB.dirInfo.ioCompletion=NULL;
- for( myPB.dirInfo.ioDrDirID=file->parID;
- myPB.dirInfo.ioDrDirID!=fsRtDirID;
- myPB.dirInfo.ioDrDirID=myPB.dirInfo.ioDrParID){
- myErr=PBGetCatInfo(&myPB, FALSE);
- if(myPB.dirInfo.ioResult==noErr){
- strcat(fullPath, ":");
- strcat(fullPath, PtoCstrPtr(dirName));
- }else
- break;
- }
- return fullPath;
- }
-
- /*----------------------------------------------------------------------------------
- * GetBaseName() - Converts a FSS file specification to a C string containing
- * the base file name, i.e., without the path.
- * The string the pointer points to is reused for each new call.
- *----------------------------------------------------------------------------------*/
- char *GetBaseName(FSSpec *file){
- static char fullPath[100]; /* Semi-permanent, reused. */
-
- strcpy(fullPath, PtoCstrPtr(file->name)); /* Add file name. */
- return fullPath; /* Return pointer. */
- }
-
- /*----------------------------------------------------------------------------------
- * GetFullPathName() - Converts a FSS file specification to a C string containing
- * the full path and the file name.
- * The string the pointer points to is reused for each new call.
- * See: New Inside Mac, "Files", p. 2-45: Constructing Full Pathnames, Listing 2-5.
- *----------------------------------------------------------------------------------*/
- char *GetFullPathName(FSSpec *file){
- static char fullPath[1000]; /* Semi-permanent, reused. */
-
- strcpy(fullPath, GetVolumeName(file)); /* Start with disk name. */
- strcat(fullPath, ":"); /* Path always ends with colon. */
- GetFullPath(file->vRefNum, file->parID, fullPath); /* Find full path. */
- strcat(fullPath, PtoCstrPtr(file->name)); /* Add file name. */
- return fullPath; /* Return pointer. */
- }
-
- /*----------------------------------------------------------------------------------
- * GetFullPath() - Returns full path name (without file name) in fullPath. Recursive.
- *
- * See: New Inside Mac, "Files", p. 2-45: Constructing Full Pathnames, Listing 2-5.
- * Because strcat() cannot handle overlapping strings, recursion is easier than
- * an iteration. The parts of the path are pasted together AFTER all parts are found.
- *----------------------------------------------------------------------------------
- */
- void GetFullPath(int VolumeSpec, long ParentDirID, char *fullPath){
- Str255 dirName;
- CInfoPBRec myPB;
- OSErr myErr;
-
- myPB.dirInfo.ioVRefNum=VolumeSpec;
- myPB.dirInfo.ioDrDirID=ParentDirID;
- myPB.dirInfo.ioFDirIndex= -1; /* <0: Use ioDrDirID as input. */
- myPB.dirInfo.ioCompletion=NULL;
- myPB.dirInfo.ioNamePtr=dirName; /* Output buffer for PBGetCatInfo(). */
- myErr=PBGetCatInfo(&myPB, FALSE); /* receive parent dir in dirName */
- if(myErr==noErr){
- if(myPB.dirInfo.ioDrParID!=fsRtDirID) /* This is the root dir ID. */
- GetFullPath(VolumeSpec, myPB.dirInfo.ioDrParID, fullPath); /* RECURSION */
- strcat(fullPath, PtoCstrPtr(dirName)); /* paste parent to ancestors */
- strcat(fullPath, ":"); /* Path always ends with colon. */
- }
- return;
- }
-
- /*----------------------------------------------------------------------------------
- * FSSpecRoutinesAvail() - Returns true if the FSS functions are available.
- *----------------------------------------------------------------------------------
- */
- int FSSpecRoutinesAvail(void){
- OSErr myErr = !noErr;
- long myFeature;
- int avail=0;
-
- if(1/*gHasGestalt()*/){
- myErr=Gestalt(gestaltFSAttr, &myFeature);
- if(myErr==noErr && (myFeature & gestaltHasFSSpecCalls))
- avail=1;
- else
- Log("Gestalt error");
- }else
- Log("Gestalt is not available");
-
- if(avail)
- Log("FSS Routines Available");
-
- return avail;
- }
-
- /*----------------------------------------------------------------------------------
- * select_input_file() - Allows the user to select an input file with a standard dialog box.
- * If numTypes == -1, all file types are displayed.
- * Returns: pointer to FSS record, or NULL on error or cancel.
- * See: New Inside Mac, "Files", p. 1-19: Opening a File, Listing 1-6.
- *----------------------------------------------------------------------------------*/
- FSSpec *select_input_file(const int numTypes, SFTypeList myTypes){
- static StandardFileReply myReply;
- OSErr myErr=noErr;
-
- StandardGetFile(NULL, numTypes, myTypes, &myReply);
- if(myReply.sfGood){
- char type[5];
- LtoCstr(myReply.sfType, type);
- sprintf(buf, "select_input_file: Type: %s", type); Log(buf);
- return &myReply.sfFile;
- }else
- return NULL;
- }
-
- /*----------------------------------------------------------------------------------
- * select_output_file() - Allows the user to select an output file with a standard dialog box.
- * Returns: pointer to FSS record, or NULL on error or cancel.
- *----------------------------------------------------------------------------------*/
- FSSpec *select_output_file(const char *prompt, const char *defname){
- Str255 Pprompt, Pdefname;
- static StandardFileReply myReply;
- OSErr myErr=noErr;
-
- strcpy((char *)Pprompt, prompt); CtoPstr((char *)Pprompt);
- strcpy((char *)Pdefname, defname); CtoPstr((char *)Pdefname);
- /* The cursor is set to an I-beam to edit the file name in the
- * dialog box. Reset it to the default arrow. */
- StandardPutFile(Pprompt, Pdefname, &myReply);
- InitCursor();
- if(myReply.sfGood){
- return &myReply.sfFile;
- }else
- return NULL;
- }
-
- /*----------------------------------------------------------------------------------
- * FinderInfo() - Test output of Finder Info of a file: creator, type...
- *----------------------------------------------------------------------------------*/
- void FinderInfo(FSSpec *fs){
- OSErr myErr;
- FInfo fndrInfo;
- char creator[5], type[5];
-
- myErr=FSpGetFInfo(fs, &fndrInfo);
- LtoCstr(fndrInfo.fdType, type);
- LtoCstr(fndrInfo.fdCreator, creator);
-
- Log("-------------------------");
- strcpy(buf, "Getting Finder Info: ");
- switch(myErr){
- case noErr: strcat(buf, "No error"); break;
- case nsvErr: strcat(buf, "No such volume"); break;
- case ioErr: strcat(buf, "I/O error"); break;
- case bdNamErr: strcat(buf, "Bad filename"); break;
- case fnfErr: strcat(buf, "File not found"); break;
- case paramErr: strcat(buf, "No default volume"); break;
- case dirNFErr: strcat(buf, "Directory not found or incomplete pathname"); break;
- case afpAccessDenied: strcat(buf, "User does not have the correct access"); break;
- case afpObjectTypeErr: strcat(buf, "Directory not found or incomplete pathname"); break;
- default : strcat(buf, "Unknown error"); break;
- }
- Log(buf);
- if(myErr==noErr){
- sprintf(buf, "Type: '%s' Creator: '%s', Flags: 0x%04X, Location: X=%d Y=%d, Directory: %d",
- type, creator,
- fndrInfo.fdFlags, fndrInfo.fdLocation.h, fndrInfo.fdLocation.v,
- fndrInfo.fdFldr); Log(buf);
- }
- return;
- }
-
- /*----------------------------------------------------------------------------------
- * PathInfo() - Test output with info on the PathID.
- *----------------------------------------------------------------------------------*/
- void PathInfo(FSSpec *fs){
- CInfoPBRec myPB;
- Str255 dirName;
- OSErr myErr;
-
- myPB.dirInfo.ioNamePtr=dirName; /* Output buffer for PBGetCatInfo(). */
- myPB.dirInfo.ioVRefNum=fs->vRefNum; /* Volume ID */
- myPB.dirInfo.ioDrDirID=fs->parID;
- myPB.dirInfo.ioFDirIndex= -1; /* <0: Use ioDrDirID as input. */
-
- Log("-------------------------");
- myErr=PBGetCatInfo(&myPB, FALSE);
- sprintf(buf, "Getting Path Info: %s", myErr==noErr?"OK":"Error"); Log(buf);
- sprintf(buf, "ID of this dir: %ld, Parent dir: \"%s\"",
- myPB.dirInfo.ioDrDirID, PtoCstr(dirName)); Log(buf);
- sprintf(buf, "ID of parent dir: %ld, Files in dir: %d",
- myPB.dirInfo.ioDrParID, myPB.dirInfo.ioDrNmFls); Log(buf);
-
- return;
- }
-
- /*----------------------------------------------------------------------------------
- * GetVolumeName() - Returns pointer to the volume name specified in fs.
- *----------------------------------------------------------------------------------*/
- char *GetVolumeName(FSSpec *fs){
- static char name[35]; /* Volume names are up to 27 chars. */
- HParamBlockRec myHPB;
- OSErr myErr;
-
- myHPB.volumeParam.ioNamePtr=(StringPtr)name;
- myHPB.volumeParam.ioVRefNum=fs->vRefNum;
- myHPB.volumeParam.ioVolIndex=0;
- myErr=PBHGetVInfo(&myHPB, FALSE);
- PtoCstr((StringPtr)name);
- return name;
- }
-
- /*----------------------------------------------------------------------------------
- * VolumeInfo() - Test output.
- *----------------------------------------------------------------------------------*/
- void VolumeInfo(FSSpec *fs){
- HParamBlockRec myHPB;
- OSErr myErr;
- char name[35]; /* Volume names are up to 27 chars. */
- long bytes, MB=1024L*1024L;
-
- myHPB.volumeParam.ioNamePtr=(StringPtr)name;
- myHPB.volumeParam.ioVRefNum=fs->vRefNum;
- myHPB.volumeParam.ioVolIndex=0;
- myErr=PBHGetVInfo(&myHPB, FALSE);
- Log("-------------------------");
- sprintf(buf, "Getting Volume Info: %s", myErr==noErr?"OK":"Error"); Log(buf);
- sprintf(buf, "Drive Number: %d, Volume Specification Number: %d",
- myHPB.volumeParam.ioVDrvInfo, myHPB.volumeParam.ioVRefNum); Log(buf);
- sprintf(buf, "Allocation Block Size: %ld bytes", myHPB.volumeParam.ioVAlBlkSiz); Log(buf);
- sprintf(buf, "Clump Size: %ld bytes", myHPB.volumeParam.ioVClpSiz); Log(buf);
- sprintf(buf, "Free: %d Allocation Blocks", myHPB.volumeParam.ioVFrBlk); Log(buf);
- bytes=myHPB.volumeParam.ioVFrBlk * myHPB.volumeParam.ioVAlBlkSiz;
- sprintf(buf, "Name: %s, Free: %ld bytes = %g MB",
- PtoCstrPtr(myHPB.volumeParam.ioNamePtr), bytes, (float)bytes/MB); Log(buf);
- return;
- }
-
- /*----------------------------------------------------------------------------------
- * TestPathUtils()
- *----------------------------------------------------------------------------------*/
- void TestPathUtils(void){
-
- FSSpecRoutinesAvail();
-
- /* Test of PtoCstrPtr(). */
- {
- char *str;
- Str255 Pstr="\pHello";
-
- str=PtoCstrPtr(Pstr);
- Log(str);
- }
-
- /* Test of select_input_file(). */
- {
- SFTypeList myTypes;
- FSSpec *fs;
-
- //myTypes[0]='TEXT';
- fs=select_input_file(-1, myTypes);
- if(fs==NULL){
- Log("Error select_input_file() or user cancelled");
- return;
- }
- FinderInfo(fs);
- VolumeInfo(fs);
- PathInfo(fs);
-
- if(fs){
- Log("-------------------------");
- Log("Getting full name");
- {
- char *fullname=FSStoCstrPtr(fs);
- sprintf(buf, "FSStoCstrPtr: %s", fullname);Log(buf);
- fullname=GetFullPathName(fs);
- sprintf(buf, "GetFullPathName: %s", fullname);Log(buf);
- }
- Log("-------------------------");
- }
- }
-
- return;
- }
-
- /*----------------------------------------------------------------------------------
- * macftype() - Changes the file type and creator if specified.
- * Example: macftype(fss, 0L, 'TEXT');
- *----------------------------------------------------------------------------------*/
- MacFILE *macftype(FSSpec *selection, long creator, long type){
- short vRefNum=selection->vRefNum;
- long dirID =selection->parID;
- Str255 fileName;
- FInfo fndrInfo;
-
- /* FSSpec.name is 63 byte string */
- memcpy(fileName, selection->name, sizeof(selection->name));
-
- HGetFInfo(vRefNum, dirID, fileName, &fndrInfo);
-
- if(creator) fndrInfo.fdCreator=creator;
- if(type) fndrInfo.fdType =type;
-
- HSetFInfo(vRefNum, dirID, fileName, &fndrInfo);
-
- return;
- }
-
- /*----------------------------------------------------------------------------------
- * macfopen() - Returns a pointer to an entry in the file table, or NULL on error.
- *----------------------------------------------------------------------------------*/
- MacFILE *macfopen(FSSpec *selection, char *mode){
-
- /* This is the file table. */
- static MacFILE mac_file_table[FOPEN_MAX]; /* Like ANSI C */
-
- int i;
- OSErr myErr;
- SignedByte permissions;
-
- if(selection==NULL) return;
-
- /* Find a free slot. */
- for(i=0; i<FOPEN_MAX && mac_file_table[i].in_use; i++);
- if(i==FOPEN_MAX)
- return NULL;
-
- /* Translate mode to permissions. */
- if(strchr(mode, 'w')){
- HParamBlockRec myHPB;
- OSErr myErr;
- long bytes, MB=1024L*1024L;
-
- myHPB.volumeParam.ioNamePtr=NULL;
- myHPB.volumeParam.ioVRefNum=selection->vRefNum;
- myHPB.volumeParam.ioVolIndex=0;
- myErr=PBHGetVInfo(&myHPB, FALSE);
- /* Check if the volume is locked. FSpOpenDF() will still open the
- * file for write access, but writing will cause an error.
- * See New Inside Mac, "Files", p. 2-8.
- * It recommends calling PGHGetVInfo(), which is described at p. 2-144.
- * HOWEVER, I can't find the description for the
- * volume attributes ioVAtrb ???
- */
- //if(myHPB.volumeParam.ioVAtrb & ????????)
- // return NULL;
- permissions=fsRdWrPerm;
- }else
- permissions=fsRdPerm;
-
- /* Open it. If file-to-write not found, create it and try again. */
- myErr=FSpOpenDF(selection, permissions, &mac_file_table[i].refnum);
-
- if(myErr==fnfErr && permissions==fsRdWrPerm)
- if(noErr==FSpCreate(selection, CREATOR, 'TEXT', smSystemScript))
- myErr=FSpOpenDF(selection, permissions, &mac_file_table[i].refnum);
-
- if(myErr!=noErr)
- return NULL;
-
- mac_file_table[i].in_use=1;
- mac_file_table[i].byteorder=BigEndian; /* Assume it is a Mac type file. */
-
- memcpy(&mac_file_table[i].fss, selection, sizeof(FSSpec));
-
- return &mac_file_table[i];
- }
-
- /*----------------------------------------------------------------------------------
- * macfclose() - Closes the file and flushes the volume, or returns non-zero on error.
- *----------------------------------------------------------------------------------*/
- int macfclose(MacFILE *fp){
- OSErr myErr;
-
- if(fp==NULL) return;
-
- myErr=FSClose(fp->refnum);
- if(myErr==noErr){
- FlushVol(NULL, fp->fss.vRefNum);
- return 0;
- }else
- return EOF;
- }
-
- /*----------------------------------------------------------------------------------
- * macfread() - Like fread().
- *----------------------------------------------------------------------------------*/
- int macfread(void *buf, size_t recsize, size_t recnum, MacFILE *fp){
- OSErr myErr=noErr;
- long count=recsize;
- int rec;
- char *Buffer=buf;
-
- if(fp==NULL) return;
-
- /* Transfer data in the chunks as specified. */
- for(rec=0; rec<recnum && myErr==noErr; rec++){
- myErr=FSRead(fp->refnum, &count, Buffer);
- Buffer += count;
- }
-
- /* Count only records that transferred successfully. */
- if(myErr!=noErr)
- rec--;
-
- /* Return how many records transferred successfully. */
- return rec;
- }
-
- /*----------------------------------------------------------------------------------
- * macfwrite() - Like fwrite().
- *----------------------------------------------------------------------------------*/
- int macfwrite(void *buf, size_t recsize, size_t recnum, MacFILE *fp){
- OSErr myErr=noErr;
- long count=recsize;
- int rec;
- char *Buffer=buf;
-
- if(fp==NULL) return;
-
- /* Transfer data in the chunks as specified. */
- for(rec=0; rec<recnum && myErr==noErr; rec++){
- myErr=FSWrite(fp->refnum, &count, Buffer);
- Buffer += count;
- }
-
- /* Count only records that transferred successfully. */
- if(myErr!=noErr)
- rec--;
-
- /* Return how many records transferred successfully. */
- return rec;
- }
-
- /*----------------------------------------------------------------------------------
- * TestFileType() - Determines what kind the open file is.
- *----------------------------------------------------------------------------------*/
- int TestFileType(MacFILE *fp){
- char buf[100];
- int i, ctrl=0, bin=0, ret=0, nl=0, esc=0, Rochester=0, Hathaway=0, ps=0;
-
- if(fp==NULL) return;
-
- if(1==macfread(buf, sizeof(buf), 1, fp)){
- /* Test for headers. */
- if(!strncmp(buf, "%!", 2)) ps++;
- if(!strncmp(buf, "DSM version ", 12)) Hathaway++;
- /* Does the Rochester file have a header? */
-
- /* Test the bytes. */
- for(i=0; i<sizeof(buf); i++){
- switch(buf[i]){
- case '\r': ret++; break;
- case '\n': nl++; break;
- case 0x1B: esc++; break;
- case '\t': case '\f': case '\b': case '\v': break;
- default:
- if(buf[i]<0x1f) ctrl++;
- if(buf[i]>0x7f) bin++;
- break;
- }
- }
- }
-
- sprintf(buf, "ctrl=%d, bin=%d, ret=%d, nl=%d, esc=%d",
- ctrl, bin, ret, nl, esc); Log(buf);
- if(Rochester) Log("Rochester Transient Fault Recorder file");
- if(Hathaway) Log("Hathaway Digital Signal Monitor file");
- if(ps) Log("PostScript file");
- if(bin)
- Log("Binary file");
- else{
- if(!ret && nl) Log("Unix text file");
- if( ret && !nl) Log("Macintosh text file");
- if( ret && nl) Log("MS-DOS text file");
- }
-
- return 0;
- }
-
- /*----------------------------------------------------------------------------------
- * macfseek() - Like fseek().
- *----------------------------------------------------------------------------------*/
- int macfseek(MacFILE *fp, long offset, int whence){
- OSErr myErr;
- short posMode;
-
- if(!fp) return -1;
-
- switch(whence){
- case SEEK_SET: posMode=fsFromStart; break;
- case SEEK_CUR: posMode=fsFromMark; break;
- case SEEK_END: posMode=fsFromLEOF; break;
- default: return -1; break;
- }
-
- myErr=SetFPos(fp->refnum, posMode, offset);
-
- return myErr==noErr?0:-1;
- }
-
- /*----------------------------------------------------------------------------------
- * macftell() - Like ftell().
- *----------------------------------------------------------------------------------*/
- long macftell(MacFILE *fp){
- OSErr myErr;
- long offset;
-
- if(!fp) return -1;
-
- myErr=GetFPos(fp->refnum, &offset);
- if(myErr!=noErr) errno=1; /* Required by ANSI C standard. */
-
- return myErr==noErr?offset:-1L;
- }
-
- /*----------------------------------------------------------------------------------
- * macfstat() - Get file status. Returns zero on success, or -1 on error.
- * Not all unix features are implemented yet.
- *----------------------------------------------------------------------------------*/
- int macfstat(MacFILE *fp, struct MacStat *buf){
- static char name[35]; /* Volume names are up to 27 chars. */
- HParamBlockRec myHPB; /* New Ins.Mac, `Files', p. 2-269 */
- OSErr myErr;
- DateTimeRec date;
-
- if(!buf) return -1;
-
- myHPB.volumeParam.ioCompletion=0;
- myHPB.volumeParam.ioNamePtr=(StringPtr)fp->fss.name;
- myHPB.volumeParam.ioVRefNum=fp->fss.vRefNum;
- myHPB.fileParam.ioFDirIndex=0;
- myHPB.fileParam.ioDirID=fp->fss.parID;
- myErr=PBHGetFInfo(&myHPB, FALSE); /* New Ins.Mac, `Files', p. 2-194 */
-
- Secs2Date(myHPB.fileParam.ioFlMdDat, &date);
- buf->year=date.year;
-
- return myErr==noErr?0:-1;
- }
-
- /*----------------------------------------------------------------------------------
- * copy_file() - For testing.
- *----------------------------------------------------------------------------------*/
- void copy_file(MacFILE *fp_in, MacFILE *fp_out){
- #define recsiz 100
- char rec[recsiz];
- int irec, nrec, lrec;
- long fsiz;
-
- if(!fp_in || !fp_out) return;
-
- /* File size. */
- macfseek(fp_in, 0L, SEEK_END);
- fsiz=macftell(fp_in);
- nrec=fsiz/recsiz;
- lrec=fsiz-(nrec*recsiz); /* Size of last, partial, record. */
- macfseek(fp_in, 0L, SEEK_SET);
- macfseek(fp_out, 0L, SEEK_SET);
- sprintf(buf, "File size: %ld bytes = %d chunks of %d bytes plus one of %d bytes",
- fsiz, nrec, recsiz, lrec); Log(buf);
-
- /* Transfer full records. */
- for(irec=0; irec<nrec; irec++){
- if(1!=macfread (rec, recsiz, 1, fp_in)) break;
- if(1!=macfwrite(rec, recsiz, 1, fp_out)) break;
- }
-
- /* Transfer the last, partial record. */
- if(lrec && 1==macfread(rec, lrec, 1, fp_in))
- macfwrite(rec, lrec, 1, fp_out);
-
- Log("Copy Done.");
- return;
- }
-
- /*----------------------------------------------------------------------------------
- * TestFileUtils()
- *----------------------------------------------------------------------------------*/
- void TestFileUtils(void){
- MacFILE *fp_in, *fp_out;
- FSSpec *fs_in, *fs_out;
- SFTypeList myTypes;
- StandardFileReply myReply;
-
- Log("Testing the file utility functions");
-
- fs_in=select_input_file(-1, myTypes); /* Input file */
- fp_in=macfopen(fs_in, "r");
-
- TestFileType(fp_in);
-
- StandardPutFile("\pFormat: see diagnostic window", "\pdummy", &myReply);
- fs_out=myReply.sfGood?&myReply.sfFile:NULL;
- fp_out=macfopen(fs_out, "w");
-
- copy_file(fp_in, fp_out);
-
- macfclose(fp_in);
- macfclose(fp_out);
-
- return;
- }
-
- /*----------------------------------------------------------------------------------
- * BetterMoveWindow() - Moves the window partially down and to the right with
- * amounts between 0 and 1, where the entire screen size is one.
- * The window will not get too close to the border.
- *----------------------------------------------------------------------------------*/
- void BetterMoveWindow(WindowPtr wp, float right, float down){
- Rect r;
- short h, w, x, y;
-
- /* Move the box to the center of the screen, horizontally, and
- * one-third down, but not too close to the border.
- * This is difficult to do with RezEdit.
- */
- r=wp->portRect;
- h=r.bottom-r.top; /* height */
- w=r.right-r.left; /* width */
- x=(screenBits.bounds.right-w) * right;
- if(x<10) x=10;
- y=(screenBits.bounds.bottom-30-h) * down +30; /* Menubar is 30 pixels high. */
- if(y<30) y=30;
- MoveWindow(wp, x, y, TRUE);
- }
-
-
- /*----------------------------------------------------------------------------------
- * SwapN() - swaps n bytes of buf in place, also convert IEEE 8-byte double to
- * Macintosh double (12-byte)
- *----------------------------------------------------------------------------------*/
- void SwapN(void *buf, int n){
- char c, *b, *e;
- for(b=buf, e=b+n-1; b<e; b++, e--){
- c = *b;
- *b = *e;
- *e = c;
- }
- return;
- }
-
- /*----------------------------------------------------------------------------------
- * NeedSwap() - swaps n bytes of buf in place, also convert IEEE 8-byte double to
- * Macintosh double (12-byte), BUT ONLY IF NEEDED, i.e., if the byte
- * order of the CPU running this program is different from the file type.
- * Returns: True if swap was needed.
- *----------------------------------------------------------------------------------*/
- int NeedSwap(MacFILE *fp, void *buf, int n){
- if(computerbyteorder != fp->byteorder){
- SwapN(buf, n);
- return 1;
- }else
- return 0;
- }
-
- /*==================== INPUT FUNCTIONS =================*/
-
- char GetInputByte(File *fp){
- char buf;
- long size=sizeof(buf);
- FileRead(&buf, size, 1, fp);
- return buf;
- }
-
- int GetInputInt(File *fp){
- int buf;
- long size=sizeof(buf);
- FileRead((char *)&buf, size, 1, fp);
- NeedSwap(fp, &buf, sizeof(buf));
- return buf;
- }
-
- long GetInputLong(File *fp){
- long buf;
- long size=sizeof(buf);
- FileRead((char *)&buf, size, 1, fp);
- NeedSwap(fp, &buf, sizeof(buf));
- return buf;
- }
-
- unsigned long GetInputULong(File *fp){
- unsigned long buf;
- long size=sizeof(buf);
- FileRead((char *)&buf, size, 1, fp);
- NeedSwap(fp, &buf, sizeof(buf));
- return buf;
- }
-
- float GetInputFloat(File *fp){
- float buf;
- long size=sizeof(buf);
- FileRead((char *)&buf, size, 1, fp);
- NeedSwap(fp, &buf, sizeof(buf));
- return buf;
- }
-
- /*
- Note: make sure to use the 8-byte IEEE-compatible short double on the Mac
- and not one of the Mac native 80 or 96 bit (10 or 12 byte) formats.
- */
- double GetInputDouble(File *fp){
- double retval;
- #ifdef THINK_C
- short double buf; /* IEEE-compatible 8-byte floating point on Mac. */
- #else
- double buf;
- #endif
- long size=sizeof(buf);
- FileRead((char *)&buf, size, 1, fp);
- NeedSwap(fp, &buf, sizeof(buf));
- retval=buf; /* Convert to Mac native format. */
- return retval;
- }
-
- char *GetInputString(char *str, int len, File *fp){
- int i, itemsread;
- char buf;
- long size=sizeof(buf);
-
- for(i=0; i<len && buf && itemsread; i++){
- itemsread=FileRead((char *)&buf, size, 1, fp);
- *str=buf;
- str++;
- }
-
- *str='\0';
-
- return str;
- }
-
- char *GetInputNString(char *str, int len, File *fp){
- int itemsread;
-
- itemsread=FileRead(str, 1, len, fp);
- if(str[itemsread-1]!='\0')
- str[itemsread]='\0';
-
- return str;
- }
-
- /*==================== OUTPUT FUNCTIONS =================*/
-
- // Writes a C string to the output file.
- int WriteTxt(File *fp, char *str){
- return FWRITE(str, strlen(str), 1, fp);
- }
-
- // Writes bytes to a binary output file.
- int WriteBin(File *fp, void *buf, int size){
- return FWRITE(buf, size, 1, fp);
- }
-
- void WriteULong(File *fp, unsigned long x){
- unsigned long buf; // copy the data x, it may be a constant
- buf=x;
- NeedSwap(fp, &buf, sizeof(buf));
- WriteBin(fp, &buf, sizeof buf);
- }
-
- void WriteLong(File *fp, long x){
- long buf;
- buf=x;
- NeedSwap(fp, &buf, sizeof(buf));
- WriteBin(fp, &buf, sizeof buf);
- }
-
- void WriteShort(File *fp, signed short x){
- signed short buf;
- buf=x;
- NeedSwap(fp, &buf, sizeof(buf));
- WriteBin(fp, &buf, sizeof buf);
- }
-
- ---------------------------
-
- >From reinder@neuretp.biol.ruu.nl (Reinder Verlinde)
- Subject: How to detect whether Debugger is installed?
- Date: Mon, 11 Jul 1994 12:10:44 GMT
- Organization: Rijksuniversiteit Utrecht
-
- The subject says it all: How do you detect whether MacsBug is present?
- I want to know this since I have this FKEY which should activate
- MacsBug,
- and not do anything when MacsBug is not present. The usual
- TrapAvailable
- method does not seem to work since
-
- GetTrapAddress( _Unimplemented) == GetTrapAddress( _Debugger)
-
- irrespective of the presence of MacsBug. I also looked up the Gestalt
- selectors, and there is one to check whether the Debugger Utilities are
- present, but I can't find one to check the presence of the Debugger.
-
- I can think of numerous imperfect ways to check this (comparing first
- bytes of _Unimplemented with a copy in my code, checking for MacsBug in
- the System Folder, etcetera), but there should be a perfect way.
-
- reinder@neuretp.biol.ruu.nl (Reinder Verlinde)
-
- +++++++++++++++++++++++++++
-
- >From busfield@hurricane.seas.ucla.edu (John D. Busfield)
- Date: Wed, 13 Jul 1994 16:14:40 GMT
- Organization: School of Engineering & Applied Science, UCLA.
-
- In <1994Jul11.121044.4311@cc.ruu.nl> reinder@neuretp.biol.ruu.nl (Reinder Verlinde) writes:
-
- >The subject says it all: How do you detect whether MacsBug is present?
- >I want to know this since I have this FKEY which should activate
- >MacsBug,
- >and not do anything when MacsBug is not present.
-
- Here's what it says in Macsbug Reference and Debugging Guide pg 412
-
- How MacsBug installs itself.
-
- When a system error or 68000 exception occurs, the ROM code examines
- the global variable MacJmp to obtain the address of the debuggers entry
- point. MacJmp might contain additional information, depending on whether you
- are running under a 24-bit or 32-bit Memory Manager.
-
- If you are running under a 24-bit Memory Manager, the high-order byte
- of MacJmp is a flags byte that contains the following information.
-
- Bit Meaning
- 7 Set if debugger is running
- 6 Set if debugger can handle system errors
- 5 Set if debugger is installed
- 4 Set if debugger can support the Discipline utility
-
- The lower 3 bytes of MacJmp are used to store the address of the debugger's
- entry point.
-
- If you are running under a 32-bit Memory Manager, the flags byte is
- moved to address $BFF and the long word at MacJmp becomes a full 32-bit
- address that points to the debugger's entry point.
-
- So to answer your question, you should only need to look at bit 5 of
- the flags byte.
-
- --
- - ----------------------------------------------------------------------------
- John Busfield | All my realities are virtual
- busfield@hurricane.seas.ucla.edu
- _____________________________________________________________________________
-
- +++++++++++++++++++++++++++
-
- >From dlamkins@tiac.net (David B. Lamkins)
- Date: 17 Jul 1994 00:48:29 GMT
- Organization: DBL Systems
-
- In article <1994Jul11.121044.4311@cc.ruu.nl>
- reinder@neuretp.biol.ruu.nl (Reinder Verlinde) writes:
-
- > The subject says it all: How do you detect whether MacsBug is present?
-
- The following Pascal unit does everything you need (except give you C
- code.) The Apple manual doesn't tell the entire story -- the comments
- in the code tell which debuggers and system patches break the rules.
-
- unit DebuggerTest;
-
- interface
-
- type
- DebuggerKind = ( {}
- debuggerKindNone, {}
- debuggerKindMacsBug, {}
- debuggerKindTMON, {}
- debuggerKindJasik, {}
- debuggerKindABZmon, {}
- debuggerKindOther {}
- );
- DebuggerSignature = packed array[1..2] of Char;
-
- {$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
- procedure GetDebuggerInfo (var present, active: Boolean; var kind:
- DebuggerKind; var signature: DebuggerSignature);
- {$ENDC}
-
- {ABZmon can load Ron top ofS another debugger. In this case, the
- underlying debugger}
- {becomes the secondary debugger, but is the only one reported by
- GetDebuggerInfo, which}
- {looks in the RnormalS places before trying to find ABZmon. The
- ABZMonIsLoaded function}
- {can be used to detect ABZmonUs presence when not the only debugger.}
- function ABZMonIsLoaded: Boolean;
-
- function DebuggerPresent: Boolean;
-
- implementation
-
- function ValidDebuggerWorldAddress (p: univ Ptr): Boolean;
- begin
- {Address must be even and somewhere within addressable RAM or ROM.}
- ValidDebuggerWorldAddress := not ODD(ORD(p)) and (ORD(p) >= 0) and
- (ORD(p) < ORD(MFTopMem));
- end;
-
- type
- LongPtr = ^Longint;
- IntPtr = ^Integer;
- PtrPtr = ^Ptr;
-
- function GetVBR: Ptr;
- inline
- $7008, {MOVEQ #$EnterSupervisorMode,D0}
- $A08D, {_DebugUtil}
- $4E7A, $8801, {MOVEC VBR,A0}
- $46C0, {MOVE D0,SR ;restore user mode}
- $2E88; {MOVE.L A0,(A7)}
-
- function ABZMonIsLoaded: Boolean;
- const
- _DebugUtil = $A08D;
- _Unimplemented = $A89F;
- var
- VBR: Ptr;
- vectorPtr: PtrPtr;
- codePtr: LongPtr;
- err: OSErr;
- begin
- {Alain BirtzUs ABZmon doesnUt use MacJmp at all. In fact, it doesnUt
- even use}
- {the trap dispatcher table. Instead, it patches the trap dispatcher!
- The hint for}
- {finding this, aside from not finding it anywhere else, is that ABZmon
- defines}
- {a private trap _DebugNum $AAFF - this has reserved bit 9 set.
- ABZmonUs trap}
- {dispatcher can be identified by its first instruction, ORI #$700,SR.
- In hex, this}
- {is $007C0700.}
- if GetOSTrapAddress(_DebugUtil) = GetToolTrapAddress(_Unimplemented)
- then
- VBR := Ptr(0)
- else
- begin
- if DebuggerGetMax >= 8 then
- VBR := GetVBR
- else
- VBR := Ptr(0);
- end;
- if ValidDebuggerWorldAddress(VBR) then
- begin
- vectorPtr := PtrPtr(ORD(VBR) + $28);
- codePtr := LongPtr(vectorPtr^);
- ABZMonIsLoaded := ValidDebuggerWorldAddress(codePtr) & (codePtr^ =
- $007C0700);
- end
- else
- ABZMonIsLoaded := False;
- end;
-
- {$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
- function NonStandardDebuggerKind (entry: univ Ptr): DebuggerKind;
- begin
- NonStandardDebuggerKind := debuggerKindOther; {If we canUt decideI}
-
- {JasikUs RThe DebuggerS doesnUt have a world pointer. Its
- distinguishing}
- {feature is a test for whether it was entered via an F-line trap, by
- executing}
- {the instruction CMPI #10,DSErrCode. In hex this is $0C7800100AF0.}
- if (LongPtr(entry)^ = $0C780010) and (IntPtr(ORD(entry) +
- SIZEOF(Longint))^ = $0AF0) then
- NonStandardDebuggerKind := debuggerKindJasik
- else
-
- {Add other tests as needed.}
- ;
- end;
- {$ENDC}
-
- {This is based on info from RMacsBug Reference and Debugging Guide for
- MacsBug version 6.2S}
- {The MacsBug reference doesnUt mention that the ROM debugger
- masquerades as a real debugger.}
- {Because the ROM debugger doesnUt have a RworldS pointer, we have to do
- some extra checks.}
- procedure GetDebuggerInfo (var present, active: Boolean; var kind:
- DebuggerKind; var signature: DebuggerSignature);
- const
- {The first and current universal ROM is rev 1660. Assume}
- {that future universal ROMs will have higher rev numbers.}
- UnivROMVersion = 1660;
- MacJmp = $120;
- Debug32Flags = $BFF;
- ROMBase = $2AE;
- DebugInstalledFlagBit = 5;
- DebugActiveFlagBit = 7;
- Megabyte = $100000;
- {The following gestalt selectors are from Rene G.A. RosU SGSL.}
- gestaltEnablerAttr = 'bugy'; {32-bit System Enabler [1.0]}
- gestaltEnabler32bit = 7; {32-bit enabler present}
- type
- PtrPtr = ^Ptr;
- IntPtr = ^Integer;
- SigPtr = ^DebuggerSignature;
- var
- err: OSErr;
- gestaltResult: Longint;
- MM32Bit, univROM, apple32BitEnabler, broken: Boolean;
- debugFlagsAddr: Ptr;
- debugEntryAddr, debugWorldAddr, ROMBaseAddr: Ptr;
- begin
- err := Gestalt(gestaltAddressingModeAttr, gestaltResult);
- MM32Bit := (err = noErr) & BTST(gestaltResult,
- gestalt32BitAddressing);
- err := Gestalt(gestaltROMVersion, gestaltResult);
- UnivROM := (err = noErr) & (gestaltResult >= UnivROMVersion);
- err := Gestalt(gestaltEnablerAttr, gestaltResult);
- apple32BitEnabler := (err = noErr) & BTST(gestaltResult,
- gestaltEnabler32bit);
- {According to the reference, debugger flags are located in the high
- byte of}
- {MacJmp unless the machine is 32-bit capable, in which case they move
- to}
- {$BFF. IUm not sure I believe that the 32-bit enablers (ConnectixUs
- MODE32}
- {and AppleUs 32-bit System Enabler) report the right thing w.r.t.
- 32-bit capability.}
- {Clearly, if the machine is running in 32-bit mode, itUs 32-bit
- capable even under}
- {the enablers. But when running under a 32-bit enabler in 24-bit mode,
- the enabler}
- {would seem to be obliged to report 32-bit capability. In this state,
- I wouldnUt expect}
- {the enabler to put up enough of a charade to move the debugger flags
- Q theyUd almost}
- {certainly end up in the high byte of MacJmp. Also, AppleUs enabler is
- damaged in}
- {the opposite case Q the debugger traps still look at the high byte of
- MacJmp even in}
- {32-bit mode. This requires a special test to pretend thereUs no
- debugger present under}
- {AppleUs 32-bit System Enabler in 32-bit addressing mode; 24-bit mode
- is OK.}
- broken := apple32BitEnabler and MM32Bit;
- if not broken then
- begin
- if MM32Bit or UnivROM then
- debugFlagsAddr := Ptr(Debug32Flags)
- else
- debugFlagsAddr := Ptr(MacJmp);
- present := BTST(debugFlagsAddr^, DebugInstalledFlagBit);
- active := BTST(debugFlagsAddr^, DebugActiveFlagBit);
- end
- else
- begin
- present := False;
- active := False;
- end;
- if present then
- begin
- debugEntryAddr := StripAddress(PtrPtr(MacJmp)^);
- ROMBaseAddr := StripAddress(PtrPtr(ROMBase)^);
- if ORD(debugEntryAddr) > ORD(ROMBaseAddr) then {Could be the ROM
- debuggerI}
- if MM32Bit then
- begin {In 32-bit mode, any address in or beyond ROM is not in
- RAM.}
- present := False;
- Exit(GetDebuggerInfo);
- end
- else if ORD(debugEntryAddr) <= ORD(ROMBaseAddr) + Megabyte then
- begin {In 24-bit mode, the ROM gets 1MB and can be followed by
- RAM.}
- present := False;
- Exit(GetDebuggerInfo);
- end;
- {$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
- debugWorldAddr := PtrPtr(ORD(debugEntryAddr) - SIZEOF(Ptr))^;
- if ValidDebuggerWorldAddress(debugWorldAddr) then
- signature := SigPtr(debugWorldAddr)^
- else
- signature := '??';
- case Integer(signature) of
- $4D54: {MT}
- kind := debuggerKindMacsBug;
- {% This is from memory; I _think_ TMON registers itself this wayI}
- $5748: {WH}
- kind := debuggerKindTMON;
- otherwise
- kind := NonStandardDebuggerKind(debugEntryAddr);
- end;
- {$ENDC}
- end
- {Alain BirtzUs ABZmon doesnUt put anything in MacJmp, but patches the
- trap dispatcher.}
- else if ABZMonIsLoaded then
- begin
- kind := debuggerKindABZmon;
- {$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
- signature := '??';
- {$ENDC}
- present := True;
- end
- else {No debugger present.}
- begin
- kind := debuggerKindNone;
- {$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
- signature := ' ';
- {$ENDC}
- end;
- end;
-
- function DebuggerPresent: Boolean;
- var
- present, active: Boolean;
- kind: DebuggerKind; {this never gets a value}
- signature: DebuggerSignature; {this never gets a value}
- begin
- GetDebuggerInfo(present, active, kind, signature);
- DebuggerPresent := present;
- end;
-
- end.
-
- Dave
- - --
- CPU Cycles: Use them now or lose them forever...
-
- ---------------------------
-
- >From bb@lightside.com (Bob Bradley)
- Subject: Q: Converting PB to FSSpec
- Date: Fri, 22 Jul 1994 08:56:47 -0800
- Organization: SS Software Inc.
-
- I'm writing an application that needs to process all files/folders in a
- folder/disk.
-
- I have this much so far (hasn't been tested) that I've mostly copied &
- modified from DragonSmith and DropShell 2.0 to make them work FSSpec's:
-
- OSErr FSpProcessDirectoryContents( FSSpec *directory, FSSpecList fileList,
- Boolean addDirectories,
- Boolean lookInsideDirectories,
- Boolean skipOnError )
- {
- OSErr error = noErr;
- CInfoPBRec pb;
- short i;
- Str63 name;
- Boolean keepGoing;
- long directoryID;
- FSSpec file;
-
- error = FSpGetDirectoryID( directory, &directoryID );
- if( error != noErr ) return( error );
- pb.hFileInfo.ioCompletion = NULL;
- pb.hFileInfo.ioNamePtr = &name[0];
- for( i = 1, keepGoing = TRUE; keepGoing; i++ )
- {
- pb.hFileInfo.ioVRefNum = directory->vRefNum;
- pb.hFileInfo.ioDirID = directoryID;
- pb.hFileInfo.ioFDirIndex = i;
- error = PBGetCatInfoSync( &pb );
- if( error == noErr )
- {
-
- // Right here I need something to convert the parameter block to
- // an FSSpec for this item in the directory. So I can pass it
- // my routine that either adds it to the FSSpec List (if it's a
- // file) or calls this routine again (if it's a folder).
-
- }
- else if( error == fnfErr || !skipOnError )
- {
- keepGoing = FALSE;
- }
- }
- if( error == fnfErr ) error = noErr;
- return( error );
- }
-
- Can I just copy the pb->h.fileParam.ioNamePtr, pb->c.hFileInfo.ioFlParID,
- and pb.hFileInfo.ioVRefNum fields of the parameter block to the the
- FSSpec? or do I need to do some other stuff? Do I need to any special
- handling of alias's?
-
- If you find errors in the above routine, I'd like to know about that too.
-
- +++++++++++++++++++++++++++
-
- >From woody@alumni.caltech.edu (William Edward Woody)
- Date: 24 Jul 1994 19:37:26 GMT
- Organization: California Institute of Technology, Alumni Association
-
- > FSSpec file;
- >
- > error = FSpGetDirectoryID( directory, &directoryID );
- > if( error != noErr ) return( error );
- > pb.hFileInfo.ioCompletion = NULL;
- > pb.hFileInfo.ioNamePtr = &name[0];
- > for( i = 1, keepGoing = TRUE; keepGoing; i++ )
- > {
- > pb.hFileInfo.ioVRefNum = directory->vRefNum;
- > pb.hFileInfo.ioDirID = directoryID;
- > pb.hFileInfo.ioFDirIndex = i;
- > error = PBGetCatInfoSync( &pb );
- > if( error == noErr )
- > {
- >
- > // Right here I need something to convert the parameter block to
- > // an FSSpec for this item in the directory. So I can pass it
- > // my routine that either adds it to the FSSpec List (if it's a
- /*
- * Then there's my favorite way to do this
- */
-
- FSMakeFSSpec(directory->vRefNum,directoryID,pb.hFIleInfo.ioNamePtr,&file);
-
- /*
- * Or something like that, your milege may vary.
- */
-
- > // file) or calls this routine again (if it's a folder).
- >
- > }
-
- I hope this helps.
-
- Like Apple says: Don't build the FSSpec by hand yourself. Instead,
- use FSMakeFSSpec() [IM VI Ch 25, pg 30] to do the dirty work.
-
- - Bill
- --
- - William Edward Woody | Disclamer:
- woody@alumni.cco.caltech.edu | "He who knows does not speak;
- - In Phase Consulting | He who speaks does not know."
- 337 West California #4; Glendale, CA 91203 | - Lao Tzu
-
- +++++++++++++++++++++++++++
-
- >From mclow@san_marcos.csusm.edu (Marshall Clow)
- Date: Sat, 23 Jul 1994 15:40:48 -0800
- Organization: Aladdin Systems
-
- In article <bb-2207940856470001@user59.lightside.com>, bb@lightside.com
- (Bob Bradley) wrote:
-
- > I'm writing an application that needs to process all files/folders in a
- > folder/disk.
- >
- > I have this much so far (hasn't been tested) that I've mostly copied &
- > modified from DragonSmith and DropShell 2.0 to make them work FSSpec's:
- >
- I always like to see people using DropShell! I will admit to being a
- little confused, though. The folder walking code in DropShell uses FSSpecs
- already, so I don't know what modifications you need to make.
-
- [ start of included code deleted ]
- > error = PBGetCatInfoSync( &pb );
- > if( error == noErr )
- > {
- >
- > // Right here I need something to convert the parameter block to
- > // an FSSpec for this item in the directory. So I can pass it
- > // my routine that either adds it to the FSSpec List (if it's a
- > // file) or calls this routine again (if it's a folder).
- >
- [ end of included code deleted ]
- >
- > Can I just copy the pb->h.fileParam.ioNamePtr, pb->c.hFileInfo.ioFlParID,
- > and pb.hFileInfo.ioVRefNum fields of the parameter block to the the
- > FSSpec? or do I need to do some other stuff? Do I need to any special
- > handling of alias's?
-
-
- Well, let's take your q's one at a time.
-
- 1) You _can_ just copy the relevant fields of the param block into an
- FSSpec, and go from there. This is what the DropShell does, and it will
- work. However, Apple has advised against building FSSpecs by hand, and
- recomends calling FSMakeFSSpec instead.
-
- 2) If you want to resolve alias files while you are walking the file tree,
- you can just call ResolveAliasFile () which will do all the alias
- traversal for you. _However_, you need to ensure that your loop will
- terminate. Imagine the following case:
-
- You have a folder "one"
- Inside it is a folder "two"
- inside it is a file "three"
- and a file "four", which is an alias to "one".
-
- Have fun.
- -- Marshall
-
- --
- Marshall Clow
- Aladdin Systems
- mclow@san_marcos.csusm.edu
-
- ---------------------------
-
- >From afrancke@netcom.com (Andrew Francke)
- Subject: Q: Reentrancy and PowerMac Runtime Model
- Date: Mon, 11 Jul 1994 03:13:46 GMT
- Organization: Netcom Online Communications Services (408-241-9760 login: guest)
-
- Even after scouring IM:PowerPC System Software, I yet labor under the
- thick delusion that there is no way to prevent concurrency/reentrancy
- on the PowerMac running native code. Whereas poking the SR worked just
- fine before to keep interrupt code from unhappily butting in while
- regular code was updating head and tail pointers on lists, there seems
- to be no such mention of an equivalent "Critical Section" API on
- PowerMac. Yea, verily, I believe it is not possible and am now
- contemplating abandoning all Macintosh development. Say it ain't so.
-
-
- P.S. While you're at it, tell me how it's possible to page-lock an
- arbitrary range of memory while running native. Does the VM API
- described in IM:Memory still apply? Or is it just, "tough luck --
- you'll have to put everything you want in the system heap." Finally,
- when (if ever) is the device driver interface going to be revved so
- that drivers can be written native? IMHO, this is the dirtiest secret
- kept by the Mac rags as device drivers far and away make the machine.
-
- +++++++++++++++++++++++++++
-
- >From rmah@panix.com (Robert Mah)
- Date: Mon, 11 Jul 1994 01:04:22 -0500
- Organization: One Step Beyond
-
- afrancke@netcom.com (Andrew Francke) wrote:
-
- ) Even after scouring IM:PowerPC System Software, I yet labor under the
- ) thick delusion that there is no way to prevent concurrency/reentrancy
- ) on the PowerMac running native code. Whereas poking the SR worked just
- ) fine before to keep interrupt code from unhappily butting in while
- ) regular code was updating head and tail pointers on lists, there seems
- ) ...
-
- What an extremely nasty way to check for interupts :-)
-
- I simply use the OS queue routines. Enqueue and Dequeue both disable
- interupts so you can be SURE you're VBL's, callbacks and whatnot all
- work nicely together.
-
- Cheers,
- Rob
- _____________________________________________________________________
- Robert S. Mah : Macintosh software development : 212.947.6507
- One Step Beyond : and network consulting : rmah@panix.com
-
- +++++++++++++++++++++++++++
-
- >From zstern@adobe.com (Zalman Stern)
- Date: Mon, 11 Jul 1994 08:26:28 GMT
- Organization: Adobe Systems Incorporated
-
- Andrew Francke writes
- > Even after scouring IM:PowerPC System Software, I yet labor under the
- > thick delusion that there is no way to prevent concurrency/reentrancy
- > on the PowerMac running native code. Whereas poking the SR worked just
- > fine before to keep interrupt code from unhappily butting in while
- > regular code was updating head and tail pointers on lists, there seems
- > to be no such mention of an equivalent "Critical Section" API on
- > PowerMac. Yea, verily, I believe it is not possible and am now
- > contemplating abandoning all Macintosh development. Say it ain't so.
-
- For updating queues in native code, the load-reserved/store-conditional
- mechanism is what you want to use. The mnemonics are lwarx and stwcx.
- respectively. There are examples on their usage in Appendix G of the MPC601
- User's Manual.
-
- > P.S. While you're at it, tell me how it's possible to page-lock an
- > arbitrary range of memory while running native. Does the VM API
- > described in IM:Memory still apply?
-
- It certainly should. (I.e. I haven't tried this, but I expect there's a
- moderate amount of 68k Mac software that would break if things did not work
- this way.)
- --
- Zalman Stern zalman@adobe.com (415) 962 3824
- Adobe Systems, 1585 Charleston Rd., POB 7900, Mountain View, CA 94039-7900
- `Wait a second! This is just an octahedron suspended in blue liquid.' - JT
-
- +++++++++++++++++++++++++++
-
- >From mxmora@unix.sri.com (Matthew Xavier Mora)
- Date: Mon, 11 Jul 1994 14:32:15 -0700
- Organization: SRI International
-
- In article <afranckeCsrAAz.95I@netcom.com>, afrancke@netcom.com (Andrew
- Francke) wrote:
-
- > on the PowerMac running native code. Whereas poking the SR worked just
- > fine before to keep interrupt code from unhappily butting in while
- > regular code was updating head and tail pointers on lists, there seems
- > to be no such mention of an equivalent "Critical Section" API on
- > PowerMac.
-
- This is one thing that they say will die a horrible death in Copland.
-
- Do not set SR!
-
-
-
- > you'll have to put everything you want in the system heap." Finally,
- > when (if ever) is the device driver interface going to be revved so
- > that drivers can be written native? IMHO, this is the dirtiest secret
- > kept by the Mac rags as device drivers far and away make the machine.
-
- You'll have to wait for Copland release for the new Native Driver
- support. Write them at their Applink address if you want more information.
- I don't know the address offhand. Its microkernel.<something>.
-
-
-
- Xavier
-
- --
- Matt Mora mxmora@unix.sri.com
- Testing Neswatcher
-
- +++++++++++++++++++++++++++
-
- >From quinn@cs.uwa.edu.au (Quinn "The Eskimo!")
- Date: Tue, 12 Jul 1994 10:45:59 +0800
- Organization: Department of Computer Science, The University of Western Australia
-
- In article <afranckeCsrAAz.95I@netcom.com>, afrancke@netcom.com (Andrew
- Francke) wrote:
-
- >Finally,
- >when (if ever) is the device driver interface going to be revved so
- >that drivers can be written native? IMHO, this is the dirtiest secret
- >kept by the Mac rags as device drivers far and away make the machine.
-
- You can write your drivers native, it's just that you have to have some
- 68K glue at the front and thereby take a mixed-mode switch on every entry
- to them. But even if there was a native API you'd still be taking a
- mixed-mode switch because the Device Manager (including the bit that
- fields interrupts) is emulated. So if you do a *lot* of work in your
- device driver then writing it native would make sense.
-
- All this mess is going to be sorted out in Copland. Which means that a
- lot of device drivers are going to have to be rewritten.
- --
- Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> "Support HAVOC!"
- Department of Computer Science, The University of Western Australia
- Who missed that session at WWDC and is desperately seeking the
- presentation CD.
-
- +++++++++++++++++++++++++++
-
- >From steele@isi.edu (Craig Steele)
- Date: Tue, 12 Jul 1994 12:14:30 -0800
- Organization: USC Information Sciences Institute
-
- In article <mxmora-1107941432150001@xavier.sri.com>, mxmora@unix.sri.com
- (Matthew Xavier Mora) writes:
- > You'll have to wait for Copland release for the new Native Driver
- > support. Write them at their Applink address
-
- Judging from the preliminary draft of "Designing PCI Cards and Drivers for
- Power Macintosh Computers" that arrived in my mailbox yesterday, bits of the
- future are coming a bit sooner. A final PCI Card Developer's Kit for
- PowerMacs is said to be scheduled for APDA release in the "summer of 1994."
- The PCI runtime drivers use native interfaces. You might be able to get a
- copy of the preliminary draft by contacting them at
- apple.pci.applelink.apple.com.
-
-
- Craig S. Steele, steele@isi.edu - Not yet Institutionalized
-
-
- +++++++++++++++++++++++++++
-
- >From telesis@ecf.toronto.edu (Telesis North)
- Date: Wed, 13 Jul 1994 04:19:47 GMT
- Organization: telesis north & screen door company
-
- In article <quinn-1207941045590001@edu-dynamic1.educ.ecel.uwa.edu.au>,
- Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
- >All this mess is going to be sorted out in Copland. Which means that a
- >lot of device drivers are going to have to be rewritten.
-
- Actually, _all_ the device drivers are going to have to be re-written (or
- break). That was my favourite quote out of the WWCC,
-
- "Under Copland, (current) 68K device drivers will not run."
-
- Heh.
-
- --
- Roger Pantos Telesis North, Inc. telesisnorth
- Mac Software Guy telesis@ecf.toronto.edu (AppleLink)
- Contrary to popular belief, green eggs & ham suck big time.
-
- +++++++++++++++++++++++++++
-
- >From quinn@cs.uwa.edu.au (Quinn "The Eskimo!")
- Date: Thu, 14 Jul 1994 11:20:10 +0800
- Organization: Department of Computer Science, The University of Western Australia
-
- In article <Csv2oz.KKK@ecf.toronto.edu>, telesis@ecf.toronto.edu (Telesis
- North) wrote:
-
- >In article <quinn-1207941045590001@edu-dynamic1.educ.ecel.uwa.edu.au>,
- >Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
- >>All this mess is going to be sorted out in Copland. Which means that a
- >>lot of device drivers are going to have to be rewritten.
- >
- >Actually, _all_ the device drivers are going to have to be re-written (or
- >break). That was my favourite quote out of the WWCC,
- >
- > "Under Copland, (current) 68K device drivers will not run."
-
- Well this is an interesting question. I didn't catch that session at WWDC
- but I can see no reason why software only device drivers (such .Notify and
- .Reminder) couldn't be supported. These are just using the Device Manager
- as a kludgy share library system that gives you non-interrupt time. So
- was there any comment about non-hardware device drivers?
-
- >Roger Pantos
-
- Hi Roger! Maybe if your real name was something other that Telesis North
- I'd catch your postings more often (:
- --
- Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> "Support HAVOC!"
- Department of Computer Science, The University of Western Australia
-
- +++++++++++++++++++++++++++
-
- >From rang@winternet.com (Anton Rang)
- Date: 14 Jul 1994 04:24:00 GMT
- Organization: Trillium Research, Inc.
-
- In article <afranckeCsrAAz.95I@netcom.com> afrancke@netcom.com (Andrew Francke) writes:
- >Even after scouring IM:PowerPC System Software, I yet labor under the
- >thick delusion that there is no way to prevent concurrency/reentrancy
- >on the PowerMac running native code.
-
- You're right! Well, more or less. You can change the SR by going
- back into 68K code, and since all interrupts are currently dispatched
- through the emulator, this will block them from being processed until
- you change the SR back. But (a) this will break, and (b) this will be
- incredibly slow. Don't do it if you don't have to.
-
- >Whereas poking the SR worked just
- >fine before to keep interrupt code from unhappily butting in while
- >regular code was updating head and tail pointers on lists
-
- Well, in this case you can either (a) call Enqueue/Dequeue, which is
- slow because of the mode switch but will be atomic, or (b) use a
- little assembly language to call the lwarx/stwcx instructions. Check
- your manual for details.
-
- >there seems to be no such mention of an equivalent "Critical Section"
- >API on PowerMac.
-
- There will be. Unfortunately, it's not there yet. The hardware is
- ahead of the software, currently.
-
- >P.S. While you're at it, tell me how it's possible to page-lock an
- >arbitrary range of memory while running native. Does the VM API
- >described in IM:Memory still apply?
-
- Yes, that API still works. (All the current APIs work, actually.)
-
- >Finally, when (if ever) is the device driver interface going to be
- >revved so that drivers can be written native?
-
- With the release of PCI-based Macintoshes, at first, and then with
- the next major system release (for older PowerMacs too presumably). I
- wish it were sooner, I *hate* debugging my current driver. :)
- --
- Anton Rang (rang@winternet.com)
-
- +++++++++++++++++++++++++++
-
- >From telesis@ecf.toronto.edu (Telesis North)
- Date: Thu, 14 Jul 1994 04:47:49 GMT
- Organization: Roger @ Telesis North
-
- In article <quinn-1407941120100001@edu-dynamic1.educ.ecel.uwa.edu.au>,
- Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
- >
- >Well this is an interesting question. I didn't catch that session at WWDC
- >but I can see no reason why software only device drivers (such .Notify and
- >.Reminder) couldn't be supported. These are just using the Device Manager
- >as a kludgy share library system that gives you non-interrupt time. So
- >was there any comment about non-hardware device drivers?
-
- I don't remember any; I just remember the speaker (Russell?) being
- pretty blunt about it. My understanding is that they're planning on
- ripping out the entire toolbox-level I/O architecture, along with
- the 68K-centric interrupt services, and heaving it off the dock with
- a huge sigh of relief. (It will of course be replaced with a spiffy
- new re-entrant driver model with a message-passing interface to the
- microkernel that will make life wonderful for everyone, once they've
- re-written their drivers.)
-
- I agree with your point, though. I'd say an easy 50% of the drivers
- running on my machine are just there to provide user interface hacks
- (or other software-only goodies). Come to think of it, it's probably
- mostly intercine warfare between the Now Utilities and everyone else...
-
- The problem is that most of these are so skanky, I'm not sure how far
- you'd have to go, emulation-wise, to get any level of backward
- compatibility.
-
- I suppose that one could write an early-load INIT that patched
- OpenDriver(), GetDCtlEntry() and friends, and used a faceless
- background app to provide non-interrupt time to the drivers in
- the custom entry table, but you'd still have people looking
- for familiar things in the global Unit Table in the Toolbox
- space, not to mention making asynchronous PBControl calls with
- oddball semantics... I shudder even to think about it. :-)
-
- Copland is going to break a lot of software, in the name of
- performance. Not necessarily straight-line application software,
- but lots of stand-alone gadgets and integrated systems. (Anyone
- holding out any hope for FaxSTF?)
-
- Should Apple devote engineer and QA time to emulating the old driver
- model? Tough question. I know I'm not going to - I'm going to re-write
- our drivers (and turn them into processes, most likely).
-
- >Hi Roger! Maybe if your real name was something other that Telesis North
- >I'd catch your postings more often (:
-
- Yeah, yeah. :-) I still get my news fix through an ancient Unix shell
- account that we pay a university through the nose for. I'm thinking that
- the time I could spend reading through the man pages might be better
- spent pestering people to get my Mac IP-connected. (Still, beats
- chipping out TCP packets on stone tablets, which is what we did in the
- old days...)
-
- --
- Roger Pantos Telesis North, Inc. telesisnorth
- Mac Software Guy telesis@ecf.toronto.edu (AppleLink)
- I can think of nothing more odious than a philosophy that forces its
- beliefs or its conscriptions on those who are unwilling or uninterested
- in having them.
-
- +++++++++++++++++++++++++++
-
- >From chewey@nesw.mv.com (Matthew E. Axsom)
- Date: Fri, 15 Jul 1994 13:30:42 GMT
- Organization: New England Software Works
-
- In article <quinn-1407941120100001@edu-dynamic1.educ.ecel.uwa.edu.au>,
- quinn@cs.uwa.edu.au (Quinn "The Eskimo!") wrote:
-
- > In article <Csv2oz.KKK@ecf.toronto.edu>, telesis@ecf.toronto.edu (Telesis
- > North) wrote:
- >
- > >In article <quinn-1207941045590001@edu-dynamic1.educ.ecel.uwa.edu.au>,
- > >Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
- > >>All this mess is going to be sorted out in Copland. Which means that a
- > >>lot of device drivers are going to have to be rewritten.
- > >
- > >Actually, _all_ the device drivers are going to have to be re-written (or
- > >break). That was my favourite quote out of the WWCC,
- > >
- > > "Under Copland, (current) 68K device drivers will not run."
- >
- > Well this is an interesting question. I didn't catch that session at WWDC
- > but I can see no reason why software only device drivers (such .Notify and
- > .Reminder) couldn't be supported. These are just using the Device Manager
- > as a kludgy share library system that gives you non-interrupt time. So
- > was there any comment about non-hardware device drivers?
- >
- I believe that they used that as a blanket statement at first and later
- backed away from that and said that the current driver model would still
- run as long as it was a "softwre driver" (e.g. .Reminder or .Notify) and
- not a "hardware driver". I believe they said that as long as it doesn't
- touch the hardware directly, the old drivers could still be used.
-
- -Chewey
- struct Matthew: E, Axsom { //chewey@nesw.mv.com
- Matthew(void) : E(), Axsom() {}
- Boolean macSoftwareEngineer(long future) {return future==Random();}
- Boolean newEnglandSoftwareWorks(StringPtr name) {return true;}
- };
-
- +++++++++++++++++++++++++++
-
- >From absurd@apple.com (Tim Dierks)
- Date: Fri, 22 Jul 1994 23:27:05 GMT
- Organization: Apple Computer, Inc.
-
- In article <Cswynq.Bx1@ecf.toronto.edu>, telesis@ecf.toronto.edu (Telesis
- North) wrote:
- > In article <quinn-1407941120100001@edu-dynamic1.educ.ecel.uwa.edu.au>,
- > Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
- > >
- > >Well this is an interesting question. I didn't catch that session at WWDC
- > >but I can see no reason why software only device drivers (such .Notify and
- > >.Reminder) couldn't be supported. These are just using the Device Manager
- > >as a kludgy share library system that gives you non-interrupt time. So
- > >was there any comment about non-hardware device drivers?
- >
- > I don't remember any; I just remember the speaker (Russell?) being
- > pretty blunt about it. My understanding is that they're planning on
- > ripping out the entire toolbox-level I/O architecture, along with
- > the 68K-centric interrupt services, and heaving it off the dock with
- > a huge sigh of relief. (It will of course be replaced with a spiffy
- > new re-entrant driver model with a message-passing interface to the
- > microkernel that will make life wonderful for everyone, once they've
- > re-written their drivers.)
- >
- > I agree with your point, though. I'd say an easy 50% of the drivers
- > running on my machine are just there to provide user interface hacks
- > (or other software-only goodies). Come to think of it, it's probably
- > mostly intercine warfare between the Now Utilities and everyone else...
- >
- > The problem is that most of these are so skanky, I'm not sure how far
- > you'd have to go, emulation-wise, to get any level of backward
- > compatibility.
-
- Copland will support the Device manager driver model for dispatching to
- old-style drivers; this level of compatibility should allow many drivers
- to continue to work, especially those which are software-only, and just
- manipulate data or dispatch to other drivers or toolboxes. Of course, this
- doesn't guarantee the software inside the driver will still work
- (depending on its assumptions), but we'll try to support the mechanism as
- best we can. 68K drivers which touch hardware or which get invoked to
- handle hardware interrupts will most likely not be compatible.
-
- > Copland is going to break a lot of software, in the name of
- > performance. Not necessarily straight-line application software,
- > but lots of stand-alone gadgets and integrated systems. (Anyone
- > holding out any hope for FaxSTF?)
- >
- > Should Apple devote engineer and QA time to emulating the old driver
- > model? Tough question. I know I'm not going to - I'm going to re-write
- > our drivers (and turn them into processes, most likely).
-
- Copland won't be 100% compatible, but a lot of the stuff we break we'll
- break because it's fundamentally incompatible with progress; stuff that's
- bad, but not that bad, we'll just have to see...
-
- > Roger Pantos Telesis North, Inc. telesisnorth
-
- --
- Tim Dierks
- absurd@apple.com
-
- ---------------------------
-
- >From stk@uropax.contrib.de (Stefan Kurth)
- Subject: Std filter proc trashes register D3!
- Date: 18 Jul 1994 14:40:50 +0200
- Organization: Contributed Software GbR
-
- Just discovered another system software bug: the standard filter proc
- (the one that you get with GetStdFilterProc() ) distroys the contents
- of the D3 register. Took me quite some time to figure out why one my
- variables kept changing all by itself...
-
- Is this a known bug? If not, how do I go about reporting it to Apple?
-
- ________________________________________________________________________
- Stefan Kurth Berlin, Germany stk@contrib.de
-
- +++++++++++++++++++++++++++
-
- >From D.A.G.Gillies@bradford.ac.uk (David Gillies)
- Date: Mon, 18 Jul 1994 15:13:25 GMT
- Organization: Unseen University, Ankh-Morpork
-
- In article <30dt8i$32d@uropax.contrib.de> stk@uropax.contrib.de (Stefan Kurth) writes:
- >Just discovered another system software bug: the standard filter proc
- >(the one that you get with GetStdFilterProc() ) distroys the contents
- >of the D3 register. Took me quite some time to figure out why one my
- >variables kept changing all by itself...
- >
- >Is this a known bug? If not, how do I go about reporting it to Apple?
- >
- This definitely sounds like a bug. If nothing else, the compiler should make
- callbacks safe by padding where necessary with MOVEM. It's only D0-D2 and
- A0/A1 that routines are meant to be allowed to stamp on, and compilers
- should recognize this and guard against it. I might be wrong, but this does
- seem suspicious.
-
- Personally I hate the standard filter proc, but I always prefer to roll my own.
-
- ______________________________________________________________________
- David A. G. Gillies (D.A.G.Gillies@bradford.ac.uk)
- University of Bradford, Bradford, West Yorkshire, England
- (c) 1994 Wittgenstein and The Furniture Depository of The Living Dead
-
- A little learning is a dangerous thing - but not half as dangerous as a
- lot of ignorance.
- - ---------------------REPLIES VIA EMAIL PLEASE-----------------------
- _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
-
- +++++++++++++++++++++++++++
-
- >From stk@uropax.contrib.de (Stefan Kurth)
- Date: 19 Jul 1994 01:16:49 +0200
- Organization: Contributed Software GbR
-
- In article <1994Jul18.151325.8525@bradford.ac.uk>,
- David Gillies <D.A.G.Gillies@bradford.ac.uk> wrote:
-
- > In article <30dt8i$32d@uropax.contrib.de> stk@uropax.contrib.de
- > (Stefan Kurth) writes:
- >
- > > Is this a known bug? If not, how do I go about reporting it to Apple?
- >
- > This definitely sounds like a bug.
-
- Sure it is - my question was if it is a _known_ bug... :-)
-
- > If nothing else, the compiler should make callbacks safe by padding where
- > necessary with MOVEM. It's only D0-D2 and A0/A1 that routines are meant
- > to be allowed to stamp on, and compilers should recognize this and guard
- > against it.
-
- In this case it's not the compiler's job to save registers (I mean, not _my_
- compiler's; it would have been the job of whatever compiler Apple used to
- compile their system software). The standard filter proc should save the
- registers that it uses; however, it saves only D4-D7, but also uses D3.
-
- > Personally I hate the standard filter proc, but I always prefer to roll
- > my own.
-
- Would you explain why? I have found it extremely handy. It does a lot of
- work for you.
-
- ________________________________________________________________________
- Stefan Kurth Berlin, Germany stk@contrib.de
-
- +++++++++++++++++++++++++++
-
- >From Alexander M. Rosenberg <alexr@apple.com>
- Date: Tue, 19 Jul 1994 02:20:19 GMT
- Organization: Hackers Anonymous
-
- In article <30dt8i$32d@uropax.contrib.de> Stefan Kurth, stk@uropax.contrib.de
- writes:
- > Just discovered another system software bug: the standard filter proc
- > (the one that you get with GetStdFilterProc() ) distroys the contents
- > of the D3 register. Took me quite some time to figure out why one my
- > variables kept changing all by itself...
- >
- > Is this a known bug? If not, how do I go about reporting it to Apple?
-
- Yes. Thank you for taking the time to track it down. I believe that it is
- under consideration for our next System Update release.
- - -------------------------------------------------------------------------
- - Alexander M. Rosenberg - INTERNET: alexr@apple.com - Yoyodyne -
- - 330 Waverley St., Apt B - UUCP:ucbvax!apple!alexr - Propulsion -
- - Palo Alto, CA 94301 - - Systems -
- - (415) 329-8463 - Nobody is my employer so - :-) -
- - - nobody cares what I say. - -
-
- +++++++++++++++++++++++++++
-
- >From David A Lyons <dlyons@apple.com>
- Date: Tue, 19 Jul 1994 06:00:07 GMT
- Organization: Apple Computer, Inc.
-
- In article <30dt8i$32d@uropax.contrib.de> Stefan Kurth,
- stk@uropax.contrib.de writes:
- > Just discovered another system software bug: the standard filter proc
- > (the one that you get with GetStdFilterProc() ) distroys the contents
- > of the D3 register. Took me quite some time to figure out why one my
- > variables kept changing all by itself...
- >
- > Is this a known bug? If not, how do I go about reporting it to Apple?
-
- It's a known bug in ROMs earlier than the Quadra 840av/660av; for now
- you'll have to work around it in your application.
-
- Dave Lyons
- Mr Tangent
-
- +++++++++++++++++++++++++++
-
- >From jonasw@lysator.liu.se (Jonas Wallden)
- Date: 19 Jul 1994 16:59:31 GMT
- Organization: (none)
-
- David A Lyons <dlyons@apple.com> writes:
- >In article <30dt8i$32d@uropax.contrib.de> Stefan Kurth,
- >stk@uropax.contrib.de writes:
- >> Just discovered another system software bug: the standard filter proc
- >> (the one that you get with GetStdFilterProc() ) distroys the contents
- >> of the D3 register. Took me quite some time to figure out why one my
- >> variables kept changing all by itself...
- >>
- >> Is this a known bug? If not, how do I go about reporting it to Apple?
- >
- >It's a known bug in ROMs earlier than the Quadra 840av/660av; for now
- >you'll have to work around it in your application.
- >
- >Dave Lyons
- >Mr Tangent
-
- On a related subject: I installed a memory grow proc in an application that
- uses a small heap, and that also uses StandardFile to select folders. I
- noticed that my grow proc was called while the SF dialog was being shown,
- and that SF tried to allocate a large memory block (size > 64 Kb). Of course
- it failed to find the free memory but everything works ok anyway.
-
- Is this just some cache memory that it tries to allocate for the fancy
- color icons used by Hardware System Update 3.0? I will have to check again
- to make sure it's not one of my system extensions playing a trick on me.
-
- -- Jonas Wallden
- --
- -- Jonas Wallden -- Internet: jonasw@lysator.liu.se -- AppleLink: sw1369 --
-
- +++++++++++++++++++++++++++
-
- >From dean@genmagic.com (Dean Yu)
- Date: 19 Jul 1994 18:35:23 GMT
- Organization: General Magic, Inc.
-
- In article <30dt8i$32d@uropax.contrib.de>, stk@uropax.contrib.de (Stefan
- Kurth) wrote:
- > Just discovered another system software bug: the standard filter proc
- > (the one that you get with GetStdFilterProc() ) distroys the contents
- > of the D3 register. Took me quite some time to figure out why one my
- > variables kept changing all by itself...
- >
- > Is this a known bug? If not, how do I go about reporting it to Apple?
-
- This is a known bug. (Well, I knew about it when I was there...) I seem
- to remember writing some inline code to work around this problem, but I
- don't remember what that was for.
-
- -- Dean Yu
- Negative Ethnic Role Model
- General Magic, Inc.
-
- ---------------------------
-
- >From Jim Conner <jc30@cornell.edu>
- Subject: Which NIM for serial port info?
- Date: 25 Jul 1994 02:13:58 GMT
- Organization: Cornell University
-
- Hello,
-
- I have been developing a somewhat specialized application for analysis of
- data generated by an instrument in our lab. Currently, the data is taken
- from the instrument's small display unit and entered by hand into the
- application. The data is also available from the instrument's RS-232
- port. The hope is that this data can be sent directly from the
- instrument to the Mac by way of one of the Mac's serial ports.
-
- I think that I have a grip on the hardware aspect of this connection
- (wiring one of the Mac's RS-422 serial ports so it looks like RS-232, and
- making the correct cable to the instrument). I would like to know,
- though, (1) which New Inside Macintosh book covers serial port
- manipulations, and (2) if anyone has any other references that have been
- helpful with this sort of problem.
-
- Thanks,
- Jim Conner
-
- +++++++++++++++++++++++++++
-
- >From bierman@caelab1.cae.wisc.edu (Peter Bierman)
- Date: Sun, 24 Jul 1994 23:43:13 -0500
- Organization: The Metropolis BBS <614/846-1911> Info-Mac on CD!
-
- In article <30v756$ghq@newsstand.cit.cornell.edu>, Jim Conner
- <jc30@cornell.edu> wrote:
-
-
- > I would like to know,
- > though, (1) which New Inside Macintosh book covers serial port
- > manipulations, and (2) if anyone has any other references that have been
- > helpful with this sort of problem.
- >
-
- NIM: Devices. (I don't even know if it's out yet) Chapter 5.
-
- Many people suggest "Terminal 2.2" as a great source for example code, in C.
-
- -Peter
-
- --
- Peter Bierman |"Sometimes I think that the surest sign
- bierman@caelab1.cae.wisc.edu | that intelligent life exists elsewhere
- The Metropolis 614/846-1911 | in the universe is that none of it has
- 600+MB, 2CDs, 2Lines@14.4 | tried to contact us." --Calvin
-
- ---------------------------
-
- End of C.S.M.P. Digest
- **********************
-
-
-